https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&user=Jbilyk&feedformat=atom
Alpine Linux - User contributions [en]
2024-03-28T17:47:19Z
User contributions
MediaWiki 1.40.0
https://wiki.alpinelinux.org/w/index.php?title=LXC&diff=16309
LXC
2019-09-05T21:33:47Z
<p>Jbilyk: /* Ubuntu template */</p>
<hr />
<div>[https://linuxcontainers.org/ Linux Containers (LXC)] provides containers similar BSD Jails, Linux VServer and Solaris Zones. It gives the impression of virtualization, but shares the kernel and resources with the "host".<br />
<br />
== Installation ==<br />
Install the required packages:<br />
{{Cmd|apk add lxc bridge}}<br />
<br />
If you want to create containers other than alpine you will need lxc-templates:<br />
<br />
{{Cmd|apk add lxc-templates}}<br />
<br />
== Upgrading from 2.x ==<br />
<br />
Since Alpine 3.9 we ship LXC version 3.1.<br />
LXC 3.x has major changes which will/can break your current setup.<br />
LXC 3.x will NOT ship with legacy container templates. Check your current container configs to see if you have any includes pointing to files that don't exist (shipped by legacy templates).<br />
For example if you use Alpine containers created with the alpine template you will need to install:<br />
<br />
apk add lxc-templates-legacy-alpine<br />
<br />
Also make sure you convert your LXC config files to the new 2.x format (this is now required).<br />
<br />
lxc-update-config -c /var/lib/lxc/container-name/config<br />
<br />
Make sure you have removed '''cgroup_enable''' from your cmdline as this will fail to mount cgroups and fail LXC service.<br />
<br />
== Prepare network on host ==<br />
Set up a [[bridge]] on the host. Example ''/etc/network/interfaces'':<br />
<pre><br />
auto br0<br />
iface br0 inet dhcp<br />
bridge-ports eth0<br />
</pre><br />
<br />
Create a network configuration template for the guests, ''/etc/lxc/default.conf'':<br />
<pre><br />
lxc.net.0.type = veth<br />
lxc.net.0.link = br0<br />
lxc.net.0.flags = up<br />
lxc.net.0.hwaddr = fe:xx:xx:xx:xx:xx<br />
</pre><br />
<br />
== Grsecurity restrictions ==<br />
<br />
'''NOTE''': since alpine 3.8 we no longer ship grsecurity and it should not be used in lxc setup.<br />
<br />
Some restrictions will be applied when using a grsecurity kernel (Alpine Linux default kernel).<br />
The most notable is the use of lxc-attach which will not be allowed because of GRKERNSEC_CHROOT_CAPS.<br />
To solve this we will have to disable this grsec restriction by creating a sysctl profile for lxc.<br />
Create the following file ''/etc/sysctl.d/10-lxc.conf'' and add:<br />
<pre><br />
kernel.grsecurity.chroot_caps = 0<br />
</pre><br />
<br />
There are a few other restrictions that can prevent proper container functionality. <br />
When things do not work as expected always check the kernel log with dmesg to see if grsec prevented things from happening.<br />
<br />
Other possible restrictions are:<br />
<br />
<pre><br />
kernel.grsecurity.chroot_deny_chroot = 0<br />
kernel.grsecurity.chroot_deny_mount = 0<br />
kernel.grsecurity.chroot_deny_mknod = 0<br />
kernel.grsecurity.chroot_deny_chmod = 0<br />
</pre><br />
<br />
When you finished creating your new sysctl profile you can apply it by restarting sysctl service<br />
<br />
<pre><br />
rc-service sysctl restart<br />
</pre><br />
<br />
NOTE: Always consult the [https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options Grsecurity documentation] before applying these settings.<br />
<br />
== Create a guest ==<br />
<br />
=== Alpine Template ===<br />
<br />
{{Cmd|lxc-create -n guest1 -f /etc/lxc/lxc.conf -t alpine}}<br />
<br />
This will create a ''/var/lib/lxc/guest1'' directory with a ''config'' file and a ''rootfs'' directory.<br />
<br />
Note that by default alpine template '''does not have networking service on''', you will need to add it using lxc-console<br />
<br />
<br />
If running on x86_64 architecture, it is possible to create a 32bit guest:<br />
<br />
{{Cmd|lxc-create -n guest1 -f /etc/lxc/lxc.conf -t alpine -- --arch x86}}<br />
<br />
=== Debian template ===<br />
<br />
In order to create a debian template container you will need to install some packages:<br />
<br />
{{Cmd|apk add debootstrap rsync}}<br />
<br />
Also you will need to turn off some grsecurity chroot options otherwise the debootstrap will fail:<br />
<br />
{{Cmd|echo 0 > /proc/sys/kernel/grsecurity/chroot_caps<br />
echo 0 > /proc/sys/kernel/grsecurity/chroot_deny_chroot<br />
echo 0 > /proc/sys/kernel/grsecurity/chroot_deny_mount<br />
echo 0 > /proc/sys/kernel/grsecurity/chroot_deny_mknod<br />
echo 0 > /proc/sys/kernel/grsecurity/chroot_deny_chmod<br />
}}<br />
<br />
Please remember to turn them back on, or just simply reboot the system.<br />
<br />
Now you can run:<br />
{{Cmd|SUITE{{=}}wheezy lxc-create -n guest1 -f /etc/lxc/lxc.conf -t debian}}<br />
<br />
=== Ubuntu template ===<br />
<br />
In order to create an ubuntu template container you will need to turn off some grsecurity chroot options:<br />
<br />
{{Cmd|echo 0 > /proc/sys/kernel/grsecurity/chroot_caps<br />
echo 0 > /proc/sys/kernel/grsecurity/chroot_deny_chroot<br />
echo 0 > /proc/sys/kernel/grsecurity/chroot_deny_mount<br />
echo 0 > /proc/sys/kernel/grsecurity/chroot_deny_mknod<br />
echo 0 > /proc/sys/kernel/grsecurity/chroot_deny_chmod<br />
}}<br />
<br />
Please remember to turn them back on, or just simply reboot the system.<br />
<br />
Now you can run (replace %MIRROR% with the actual hostname, for example: http://us.archive.ubuntu.com/ubuntu/)<br />
<br />
{{Cmd|lxc-create -n guest2 -f /etc/lxc/default.conf -t ubuntu -- -r xenial -a amd64 -u user --password secretpassword --mirror $MIRROR }}<br />
<br />
{{Warning|Be sure to set systemd_container to yes in /etc/conf.d/lxc.CONTAINER. Otherwise most functionality will be broken}}<br />
<br />
=== Unprivileged LXC images (Debian / Ubuntu / Centos etc..) ===<br />
<br />
{{Cmd|apk add gnupg xz<br />
lxc-create -n container-name -t download}}<br />
& choose the Distribution | Release | Architecture.<br />
<br />
To be able to login to a Debian container you currently need to:<br />
{{Cmd|rm /lib/systemd/system/container-getty\@.service}}<br />
<br />
You can also [http://without-systemd.org/wiki/index.php/How_to_remove_systemd_from_a_Debian_jessie/sid_installationers remove Systemd from the container].<br />
<br />
== Starting/Stopping the guest ==<br />
Create a symlink to the ''/etc/init.d/lxc'' script for your guest.<br />
{{Cmd|ln -s lxc /etc/init.d/lxc.guest1}}<br />
<br />
You can start your guest with:<br />
{{Cmd|/etc/init.d/lxc.guest1 start}}<br />
<br />
Stop it with:<br />
{{Cmd|/etc/init.d/lxc.guest1 stop}}<br />
<br />
Make it autostart on boot up with:<br />
{{Cmd| rc-update add lxc.guest1}}<br />
<br />
You can also add to the container config: <code>lxc.start.auto = 1</code><br />
<br />
& {{Cmd|rc-update add lxc}}<br />
<br />
to autostart containers by the lxc service only.<br />
<br />
== Connecting to the guest ==<br />
By default sshd is not installed, so you will have to attach to the container or connect to the virtual console. This is done with:<br />
<br />
=== Attach to container ===<br />
<br />
{{Cmd|lxc-attach -n guest1}}<br />
<br />
Just type exit to detach the container again (please do check the grsec notes above)<br />
<br />
=== Connect to virtual console ===<br />
<br />
{{Cmd|lxc-console -n guest1}}<br />
<br />
To disconnect from it, press {{key|Ctrl}}+{{key|a}} {{key|q}}<br />
<br />
== Deleting a guest ==<br />
Make sure the guest is stopped and run:<br />
{{Cmd|lxc-destroy -n guest1}}<br />
This will erase everything, without asking any questions. It is equivalent to: {{Cmd|rm -r /var/lib/lxc/guest1}}<br />
<br />
== Advanced ==<br />
<br />
=== Creating a LXC container without modifying your network interfaces ===<br />
<br />
The problem with bridging is that the interface you bridge gets replaced with your new bridge interface.<br />
That is to say that say you have an interface eth0 that you want to bridge, your eth0 interface gets replaced with the br0 interface that you create. It also means that the interface you use needs to be placed into promiscuous mode to catch all the traffic that could de destined to the other side of the bridge, which again may not be what you want.<br />
<br />
The solution is to create a dummy network interface, bridge that, and set up NAT so that traffic out of your bridge interface gets pushed through the interface of your choice.<br />
<br />
So, first, lets create that dummy interface (thanks to ncopa for talking me out of macvlan and pointing out the dummy interface kernel module)<br />
<br />
{{Cmd|modprobe dummy}}<br />
<br />
This will create a dummy interface called dummy0 on your host. To create this interface on every boot, you may need to create a /etc/modprobe.d/dummy.conf with:<br />
{{Cmd |# Load dummy.ko at boot<br />
dummy }}<br />
<br />
Now we will create a bridge called br0<br />
<br />
{{Cmd |brctl addbr br0<br />
brctl setfd br0 0 }}<br />
<br />
and then make that dummy interface one end of the bridge<br />
<br />
{{Cmd | brctl addif br0 dummy0 }}<br />
<br />
Next, let's give that bridged interface a reason to exists<br />
<br />
{{ Cmd | ifconfig br0 192.168.1.1 netmask 255.255.255.0 up}}<br />
<br />
Create a file for your container, let's say /etc/lxc/bridgenat.conf, with the following settings.<br />
<br />
<pre><br />
lxc.net.0.type = veth<br />
lxc.net.0.flags = up<br />
lxc.net.0.link = br0<br />
lxc.net.0.name = eth1<br />
lxc.net.0.ipv4.address = 192.168.1.2/24 192.168.1.255<br />
lxc.net.0.ipv4.gateway = 192.168.1.1<br />
lxc.net.0.veth.pair = veth-if-0<br />
</pre><br />
<br />
and build your container with that file<br />
<br />
{{ Cmd | lxc-create -n alpine -f /etc/lxc/bridgenat.conf -t alpine }}<br />
<br />
You should now be able to ping your container from your hosts, and your host from your container.<br />
<br />
Your container needs to know where to push traffic that isn't within it's subnet. To do so, we tell the container to route through the bridge interface br0<br />
From inside the container run<br />
<br />
{{ Cmd | route add default gw 192.168.1.1 }}<br />
<br />
The next step is you push the traffic coming from your private subnet over br0 out through your internet facing interface, or any interface you chose<br />
<br />
We are messing with your IP tables here, so make sure these settings don't conflict with anything you may have already set up, obviously.<br />
<br />
Say eth0 was your internet facing network interface, and br0 is the name of the bridge you made earlier, we'd do this:<br />
<br />
{{ Cmd | echo 1 > /proc/sys/net/ipv4/ip_forward<br />
iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE<br />
iptables --append FORWARD --in-interface br0 -j ACCEPT<br />
}}<br />
<br />
Now you should be able to route through your bridge interface to the internet facing interface of your host from your container, just like at home!<br />
<br />
You could also have a dhcp server running on your host, and set it up to give IP addresses from your private subnet to any container that requests it, and then have one template for multiple alpine LXC containers, perfect for alpine development :)<br />
<br />
=== Using static IP ===<br />
<br />
If you're using static IP, you need to configure this properly on guest's /etc/network/interfaces. To stay on the above example, modify ''/var/lib/lxc/guest1/rootfs/etc/network/interfaces'' <br />
<br />
from<br />
<br />
#auto lo<br />
iface lo inet loopback<br />
auto eth0<br />
iface eth0 inet '''dhcp'''<br />
<br />
to <br />
<br />
#auto lo<br />
iface lo inet loopback<br />
auto eth0<br />
iface eth0 inet '''static'''<br />
address <lxc-container-ip> # IP which the lxc container should use<br />
gateway <gateway-ip> # IP of gateway to use, mostly same as on lxc-host<br />
netmask <netmask><br />
<br />
=== mem and swap ===<br />
<br />
{{Cmd|vim /boot/extlinux.conf}}<br />
<br />
{{Cmd|<br />
APPEND initrd{{=}}initramfs-3.10.13-1-grsec root{{=}}UUID{{=}}7cd8789f-5659-40f8-9548-ae8f89c918ab modules{{=}}sd-mod,usb-storage,ext4 quiet cgroup_enable{{=}}memory swapaccount{{=}}1<br />
}}<br />
<br />
=== checkconfig ===<br />
{{Cmd|lxc-checkconfig}}<br />
<br />
{{Cmd|<br />
Kernel configuration not found at /proc/config.gz; searching...<br />
Kernel configuration found at /boot/config-3.10.13-1-grsec<br />
--- Namespaces ---<br />
Namespaces: enabled<br />
Utsname namespace: enabled<br />
Ipc namespace: enabled<br />
Pid namespace: enabled<br />
User namespace: missing<br />
Network namespace: enabled<br />
Multiple /dev/pts instances: enabled<br />
<br />
--- Control groups ---<br />
Cgroup: enabled<br />
Cgroup clone_children flag: enabled<br />
Cgroup device: enabled<br />
Cgroup sched: enabled<br />
Cgroup cpu account: enabled<br />
Cgroup memory controller: missing<br />
Cgroup cpuset: enabled<br />
<br />
--- Misc ---<br />
Veth pair device: enabled<br />
Macvlan: enabled<br />
Vlan: enabled<br />
File capabilities: enabled<br />
<br />
Note : Before booting a new kernel, you can check its configuration<br />
usage : CONFIG{{=}}/path/to/config /usr/bin/lxc-checkconfig<br />
<br />
}}<br />
<br />
=== VirtualBox ===<br />
<br />
In order for network to work on containers you need to set "Promiscuous Mode" to "Allow All" in VirtualBox settings for the network adapter.<br />
<br />
[[File:VirtualBoxNetworkAdapter.jpg]]<br />
<br />
[[Category:Virtualization]]<br />
<br />
=== postgreSQL ===<br />
<br />
Inside the container run: {{Cmd|chmod go+w /dev/null}} to fix {{Cmd|rc-service postgresql start}}<br />
<br />
=== openVPN ===<br />
<br />
see [[Setting_up_a_OpenVPN_server#openVPN_and_LXC]]<br />
<br />
== LXC 1.0 Additional information ==<br />
<br />
Some info regarding new features in LXC 1.0<br />
<br />
https://www.stgraber.org/2013/12/20/lxc-1-0-blog-post-series/<br />
<br />
== See also ==<br />
* [[Howto-lxc-simple]]</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=User_talk:Jerry&diff=11401
User talk:Jerry
2015-11-05T13:38:29Z
<p>Jbilyk: Deleting spam</p>
<hr />
<div></div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=User:Jerry&diff=11400
User:Jerry
2015-11-05T13:38:14Z
<p>Jbilyk: Deleting spam</p>
<hr />
<div></div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Xen_Dom0&diff=11030
Xen Dom0
2015-07-01T14:25:38Z
<p>Jbilyk: update for current install</p>
<hr />
<div>This guide will show you how to perform a Xen Dom0 install on a HDD, so you can have your Dom0. The first step is to perform a normal HDD install of Alpine Linux, which can be accomplished following the guide [[Install to disk]]. Once the install is finished, and you have rebooted into your new system, it's time to install the Xen packages:<br />
<br />
<pre><br />
# apk add xen xen-hypervisor<br />
</pre><br />
<br />
This will install Xen Hypervisor and Tools (both xl and xend) and all the required packages. The next step is to modify your extlinux.cfg and add an entry to boot Xen:<br />
<br />
Normal boot:<br />
<br />
<pre><br />
LABEL xen<br />
KERNEL /boot/mboot.c32<br />
APPEND /boot/xen.gz --- /boot/grsec root=UUID=<YOUR-DISK-UUID> modules=ext4 --- /boot/grsec.gz<br />
</pre><br />
<br />
Serial console boot:<br />
<pre><br />
LABEL xen<br />
KERNEL /boot/mboot.c32<br />
APPEND /boot/xen.gz com1=115200,8n1 console=com1 --- /boot/grsec root=UUID=<YOUR-DISK-UUID> modules=ext4 --- /boot/grsec.gz<br />
</pre><br />
<br />
{{Note|<nowiki>remember to change <YOUR-DISK-UUID> with the UUID of your boot disk (you can copy it from the normal Alpine Linux boot entry)</nowiki>}}<br />
<br />
It's also a good idea to check [http://wiki.xen.org/wiki/Xen_Hypervisor_Boot_Options Xen Boot options] and set dom0_mem, dom0_vcpus_pin and dom0_max_vcpus at least.<br />
<br />
The next step is to load the necessary kernel modules for Xen, we will add them to /etc/modules, so they will be loaded automatically on boot:<br />
<br />
<pre><br />
# echo "xen_netback" >> /etc/modules<br />
# echo "xen_blkback" >> /etc/modules<br />
# echo "tun" >> /etc/modules<br />
</pre><br />
<br />
The last step is to configure startup services, we will need udev and xencommons at least to be started on boot:<br />
<br />
<pre><br />
rc-update add xenconsoled<br />
rc-update add xendomains<br />
rc-update add xenqemu<br />
rc-update add xenstored<br />
</pre><br />
<br />
If you need the xm toolstack, also add xend to startup services:<br />
<br />
<pre><br />
# rc-update add xend<br />
</pre><br />
<br />
Ok, now you have a fully functional Xen install, it's time to boot into it.<br />
<br />
<pre><br />
# reboot<br />
</pre><br />
<br />
Also remember to configure at least one network bridge following the [[Bridge]] guide.<br />
<br />
== See also ==<br />
* [[Xen Dom0 on USB or SD]]<br />
<br />
[[Category:Virtualization]]</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=How_to_make_a_custom_ISO_image&diff=10679
How to make a custom ISO image
2015-04-13T13:38:27Z
<p>Jbilyk: add option to build inside LXC container</p>
<hr />
<div>This document explains how to build a custom ISO image using the alpine-iso scripts.<br />
<br />
First make sure we have the needed tools<br />
{{Cmd|apk add alpine-sdk}}<br />
<br />
Then we clone (or update) the [http://git.alpinelinux.org/cgit/alpine-iso.git/ alpine-iso git repository].<br />
{{Cmd|git clone git://git.alpinelinux.org/alpine-iso}}<br />
<br />
The alpine-iso scripts is a simple makefile which you need to feed with a ''<name>.conf.mk'' file and a ''<name>.packages''. <br />
<br />
In the ''<name>.conf.mk'' we specify<br />
<br />
;ALPINE_NAME<br />
:name of iso image<br />
<br />
;ALPINE_VERSION<br />
:(optional) version string. Will default to todays date.<br />
<br />
;KERNEL_FLAVOR<br />
:(optional) either ''grsec'', ''vserver'' or ''pae''. Will default to grsec.<br />
<br />
;MODLOOP_EXTRA<br />
:(optional) Extra kernel module packages for the modloop image. For example: ''dahdi-linux-vserver''<br />
<br />
;APK_REPOS<br />
:(optional) Path to addidtional apk repository.<br />
<br />
The ''<name>.packages'' is just a plaintext list of packages that should be included in the ISO image. You should always add ''alpine-base'' in there or the CD might not be able to boot. The dependencies for the packages will automatically be pulled in.<br />
<br />
== A rescue CD example ==<br />
As an example, let us make a rescue ISO image with packages needed for rescue operations. We call it ''alpine-rescue''<br />
<br />
We create the ''alpine-rescue.conf.mk'' as follows:<br />
ALPINE_NAME := alpine-rescue<br />
KERNEL_FLAVOR := grsec<br />
MODLOOP_EXTRA :=<br />
<br />
If you are going to use a custom kernel, don't forget to specify KERNEL_FLAVOR_DEFAULT which will set the default kernel to boot.<br />
<br />
And then the ''alpine-rescue.packages'' as:<br />
alpine-base<br />
bkeymaps<br />
openssh<br />
e2fsprogs<br />
mdadm<br />
lvm2<br />
parted<br />
debootstrap<br />
ntfs-3g<br />
<br />
{{Tip| Make sure your public keys are placed in /etc/apk/keys/ (example: root-xxxxxxxx.rsa.pub):<br />
{{Cmd|ls /etc/apk/keys/}}<br />
<br />
Learn apk-tools to find your home-built apk's:<br />
{{Cmd|echo "~/.cache/abuild/" >> /etc/apk/repositories}}<br />
}}<br />
<br />
Make sure the apk index is up to date (so apk finds the packages):<br />
{{Cmd|apk update}}<br />
<br />
We create the ISO image by telling the makefile the profile name. The makefile target is ''iso''.<br />
{{Cmd|<nowiki>make PROFILE=alpine-rescue iso</nowiki>}}<br />
<br />
{{Tip| If you are building inside an LXC guest, use fakeroot:<br />
{{Cmd|<nowiki>fakeroot make PROFILE=alpine-rescue iso</nowiki>}}<br />
}}<br />
<br />
To generate the sha1 sum we use the ''sha1'' make target.<br />
{{Cmd|<nowiki>make PROFILE=alpine-rescue sha1</nowiki>}}<br />
<br />
== Package lists ==<br />
<br />
Beside the plaintext package lists in the git repository, there are more documented package lists contributed by Alpine users. Those lists can be transformed into a plaintext to use with <tt>alpine-iso</tt> list with the simple python-based <tt>[http://git.alpinelinux.org/cgit/fab/alpine-iso/tree/config-builder.py config-builder]</tt> script.<br />
<br />
So far the lists below are available (check [[:Category:ISO|here]] for more.)<br />
<br />
* [[Alpine_mini|Alpine Mini]]<br />
* [[Alpine_rescue|Alpine Rescue]]<br />
* [[Alpine_security|Alpine Security]]<br />
* [[Alpine SCST]]<br />
<br />
== Testing your ISO image ==<br />
<br />
[[Qemu#Live_mode| Qemu]] is useful for a quick test of your created ISO image.<br />
<br />
[[Category:Package Manager]]<br />
[[Category:ISO]]</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Setting_Up_Fprobe_And_Ntop&diff=10226
Setting Up Fprobe And Ntop
2014-11-18T15:25:43Z
<p>Jbilyk: </p>
<hr />
<div>Goal: Setup fprobe as a NetFlow probe on an Alpine Linux router, and then ntop as a collector/analyzer on another machine. <br /><br />
Assumptions: Eth0 on router will be monitored, 192.168.0.1 is router interface on LAN side, 192.168.0.100 is ntop host, and port 2055 will be used for fprobe.<br />
<br />
== Router setup ==<br />
Install packages:<br />
{{cmd|apk add fprobe}}<br />
Edit /etc/conf.d/fprobe (adjust lines shown below as needed - leave rest of config file as is):<br />
IFACE=eth0<br />
FLOW_VER=7<br />
LOCALIP=192.168.0.1<br />
REMOTEIP=192.168.0.100<br />
PORT=2055<br />
Start fprobe.<br />
{{cmd|/etc/init.d/fprobe start}}<br />
<br />
== Ntop host setup ==<br />
Add package:<br />
{{cmd|apk add ntop}}<br />
Edit /etc/conf.d/ntop (adjust path to ntop cache as needed):<br />
NTOP_OPTS="-P /var/cache/ntop --http-server 3000 --https-server 0 --interface eth0"<br />
Make needed directory:<br />
mkdir /var/cache/ntop<br />
Generate ntop password:<br />
{{cmd|ntop --set-admin-password}}<br />
Start ntop:<br />
{{cmd|/etc/init.d/ntop start}}<br />
Open ntop web interface by browsing to http://192.168.0.100:3000.<br /><br />
Enable NetFlow plugin from the Plugins menu. <br /><br />
Create NetFlow device with proper options:<br />
Local Collector UDP Port: 2055<br />
Virtual NetFlow Interface Network Address: 192.168.0.100/255.255.255.0<br />
Flow Aggregation (set as desired, bu TCP/UDP Port is a good choice)<br />
Enable Session Handling: Yes<br />
Debug: Off<br />
Check after a minute or two that flows are being processed by going to the Summary -> Traffic menu option and making sure data is present for the collector port and rrd graphs are being generated.<br />
<br />
In case have trouble creating password, you can delete previous databases and recreate again:<br />
<br />
{{cmd|rm /var/ntop/ *.db}}<br />
<br />
If receive error regarding font not found you can add ttf fonts:<br />
<br />
{{cmd|apk add ttf-dejavu}}<br />
<br />
<br />
== Notes ==<br />
<br />
* To monitor 2 interfaces (gre1 given as example), copy /etc/init.d/fprobe to /etc/init.d/fprobe.gre1, edit BIN= line to point to /usr/sbin/fprobe.gre. Copy /etc/conf.d/fprobe to /etc/conf.d/fprobe.gre and change interface line to IP on gre interface and port line to 2056. Finally, softlink /usr/sbin/fprobe.gre to /usr/sbin/fprobe.<br />
* If there isn't data present, make sure firewall on both router and ntop host have port 2055 (and possibly 2056) open from the router to the ntop host.<br />
* If you have a high-volume router that you are monitoring, you may end up hitting a folder limit for your rrd interfaces directory(max of 32 000) depending on how you have flows being processed/parsed. It may be necessary to schedule a cron job to clear out the cache periodically and restart ntop after deleting the older folders.<br />
<br />
[[Category:Networking]]<br />
[[Category:Monitoring]]</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10106
Small Office Services
2014-07-20T20:49:15Z
<p>Jbilyk: /* Install Kamailio */</p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
The assumption is made that the following VLANs and subnets are used as the DMVPN document did:<br />
<br />
{|class="wikitable"<br />
!'''Interface'''<br />
!'''Description'''<br />
!'''Subnet'''<br />
|-<br />
|bond0.3<br />
|Management<br />
|10.1.0.129/26<br />
|-<br />
|bond0.101<br />
|LAN<br />
|10.1.0.0/25<br />
|-<br />
|bond0.256<br />
|Internet from ISP1<br />
|Allocated from ISP<br />
|-<br />
|bond0.257<br />
|Internet from ISP2<br />
|Allocated from ISP<br />
|-<br />
|bond0.620<br />
|Transit between wifi proxy and dmvpn spoke node<br />
|10.1.0.252/30<br />
|-<br />
|bond0.701<br />
|WiFi clients (no access to DMVPN network)<br />
|172.17.48.0/24<br />
|-<br />
|bond0.1101<br />
|Voice<br />
|10.2.0.0/24<br />
|}<br />
<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.2<br />
netmask 255.255.255.192<br />
gateway 10.1.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$10.1.0.2",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth0<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth1<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth2<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Management VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.130<br />
netmask 255.255.255.192<br />
<br />
#WiFi VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address 172.16.48.2<br />
netmask 255.255.255.0<br />
<br />
#Voice VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.2.0.2<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
up ip address add 10.2.0.3/24 dev eth0<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers 10.2.0.1;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet 10.2.0.0 netmask 255.255.255.0<br />
{<br />
range "10.2.0.20 10.2.0.250";<br />
option domain-name-servers 10.2.0.2;<br />
option routers 10.2.0.1;<br />
option boot-server "http://10.2.0.4";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet 172.17.48.0 netmask 255.255.255.0<br />
{<br />
range "172.17.48.10 172.17.48.250";<br />
option routers 172.17.48.1;<br />
option domain-name-servers 172.17.48.1; <br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: 10.2.0.2<br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: 10.2.0.3<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.2.0.2 > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: 10.2.0.3<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A 10.2.0.3<br />
<br />
;A Records for SIP Devices<br />
sip IN A 10.2.0.4<br />
media IN A 10.2.0.5<br />
<br />
;NAPTR Records<br />
sip IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp.sip IN SRV 10 100 5060 sip<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.4<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'log_destination' variable to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
<br />
== Install acf-provisioning ==<br />
* vi /etc/kamailio/kamctlrc<br />
<pre><br />
SIP_DOMAIN=sip.office.example.net<br />
DBENGINE=PGSQL<br />
DBHOST=127.0.0.1<br />
DBNAME=openser<br />
DBRWUSER=openser<br />
DBRWPW="openser"<br />
DBROUSER=openserro<br />
DBROPW=openserro<br />
DBROOTUSER="postgres"<br />
</pre><br />
* yes | kamdbctl create openser<br />
* apk add acf-provisioning lua-socket lua-expat<br />
* Create /etc/provisioning/update_device_params.lua:<br />
<pre><br />
-- This is the script run after editing device params - basically only worried about extension and password<br />
local functions, params, oldparams = ...<br />
<br />
require("posix")<br />
require("luasql.postgres")<br />
<br />
local root = "/var/www/provisioning/htdocs/"<br />
local b62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"<br />
<br />
APP.logevent("got to update_device_params script")<br />
<br />
local function generatepw()<br />
-- generate a random 12-character alphanumeric string<br />
local file = io.open("/dev/urandom")<br />
local str = ""<br />
if file == nil then return nil end<br />
local size = 12<br />
while (size > 0 ) do<br />
local offset = (string.byte(file:read(1)) % 62) + 1<br />
str = str .. string.sub (b62, offset, offset)<br />
size = size - 1<br />
end<br />
return str<br />
end<br />
<br />
local function findip(mac)<br />
if not mac or mac == "" then<br />
return nil<br />
end<br />
local ipaddr = functions.getselectresponse("SELECT ip FROM provisioning_requests WHERE mac~*'"..mac.."'")<br />
if ipaddr and ipaddr[1] then<br />
return ipaddr[1].ip<br />
end<br />
end<br />
<br />
local function addfuturenotify(ipaddr, extension)<br />
local res, err = pcall(function()<br />
functions.runsqlcommand("DELETE FROM notify WHERE ipaddr='"..ipaddr.."' AND extension='"..extension.."'")<br />
end)<br />
if not res and err then<br />
if string.match(err, "relation \"(%S+)\" does not exist") then<br />
functions.runsqlcommand("CREATE TABLE notify (ipaddr text, extension text, seasoned boolean DEFAULT false)")<br />
else<br />
assert(res, err)<br />
end<br />
end<br />
-- if table missing, create it and delete again<br />
functions.runsqlcommand("INSERT INTO notify VALUES('"..ipaddr.."', '"..extension.."')")<br />
end<br />
<br />
local notify_device = function(mac, extension)<br />
local ipaddr = findip(mac)<br />
if ipaddr then<br />
APP.logevent("Notifying "..ipaddr.." to update for "..(mac or ""))<br />
os.execute("/etc/provisioning/notify_device "..ipaddr.." "..extension)<br />
addfuturenotify(ipaddr, extension)<br />
else<br />
APP.logevent("Warning - could not find IP address for "..(mac or ""))<br />
end<br />
end<br />
<br />
local kam = APP:new("kamailio/kamailio")<br />
<br />
-- A table of devices to notify to update<br />
local devices = {}<br />
<br />
-- First, we check the registration numbers / passwords to 1) set a random password (if necessary) 2) make sure password matches any other registrations to same extension 3) push changes (add / delete / or update) to Kam database<br />
-- Because this script also handles when device classes change, we have to consider that extensions are added / removed<br />
local regs = {}<br />
local forwarding = {"forwardnoanswerenable", "forwardnoanswer", "forwardbusyenable", "forwardbusy", "forwardallenable", "forwardall"}<br />
local forwardsettings = {} -- Collect forwarding settings<br />
local passwords = {} -- Collect old extension/password pairs<br />
for name,val in pairs(params.value) do<br />
if not regs[name] and string.match(name, "^reg") then<br />
regs[name] = true<br />
end<br />
end<br />
oldparams = oldparams or {value={}}<br />
for name,val in pairs(oldparams.value) do<br />
if string.match(name, "^reg") then<br />
if val.value and val.value.extension and val.value.password then<br />
passwords[val.value.extension.value] = val.value.password.value<br />
end<br />
if val.value and val.value.extension then<br />
local fwd = {}<br />
for i,f in ipairs(forwarding) do<br />
if val.value[f] then<br />
fwd[f] = val.value[f].value<br />
end<br />
end<br />
forwardsettings[val.value.extension.value] = fwd<br />
end<br />
if not regs[name] then<br />
regs[name] = true<br />
end<br />
end<br />
<br />
end<br />
local extension_id = params.value.reg1.value.extension.param_id<br />
local password_id = params.value.reg1.value.password.param_id<br />
functions.runsqlcommand("BEGIN TRANSACTION")<br />
for name,val in pairs(regs) do<br />
local new = ""<br />
local old = ""<br />
if params.value[name] then new = params.value[name].value.extension.value end<br />
if oldparams.value[name] then old = oldparams.value[name].value.extension.value end<br />
if new ~= old then<br />
-- Extension changed<br />
-- First, let's remove the stuff for the old extension<br />
if old ~= "" then<br />
local others = functions.getselectresponse("SELECT count(*) FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..old.."'")<br />
if others[1].count == "0" then<br />
APP.logevent("Removing old registration "..old)<br />
-- remove the registration<br />
kam.model.delete_user(old)<br />
end<br />
end<br />
-- Now, add the new extension<br />
if new ~= "" then<br />
local pass<br />
if params.value[name].value.password.value ~= "" and (not oldparams.value[name] or (oldparams.value[name].value.password.value ~= params.value[name].value.password.value)) then<br />
-- The password parameter was changed and not blank, so use it<br />
pass = params.value[name].value.password.value<br />
APP.logevent("Added a new registration "..new.." with specified password "..pass)<br />
-- There may be other devices with this extension<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
-- We'll notify whether it changed or not<br />
devices[o.value] = new<br />
end<br />
elseif passwords[new] then<br />
pass = passwords[new]<br />
APP.logevent("Added a new registration "..new.." with reused password "..pass)<br />
else<br />
local others = functions.getselectresponse("SELECT * FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."' AND device_id!='"..params.value.device_id.value.."'")<br />
-- If this is a new registration, use a new password<br />
if #others == 0 then<br />
pass = generatepw()<br />
APP.logevent("Added a new registration "..new.." with random password "..pass)<br />
else<br />
-- Use the old password<br />
local p = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id='"..password_id.."' AND device_id='"..others[1].device_id.."' AND group_name='"..others[1].group_name.."' LIMIT 1")<br />
pass = p[1].value<br />
APP.logevent("Added a new registration "..new.." with reused password "..pass)<br />
end<br />
end<br />
passwords[new] = pass<br />
params.value[name].value.password.value = pass<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..password_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..password_id.."', '"..pass.."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
local u = kam.model.get_user(new)<br />
if u.value.username.errtxt then<br />
-- Add this registration to Kam<br />
local u = kam.model.get_new_user()<br />
u.value.username.value = new<br />
u.value.password.value = pass<br />
u.value.password_confirm.value = pass<br />
kam.model.create_new_user(u)<br />
else<br />
u.value.password.value = pass<br />
u.value.password_confirm.value = pass<br />
kam.model.update_user(u)<br />
end<br />
-- Let's also look at the forwarding settings<br />
local change = false<br />
local supported = false<br />
local fwd = {}<br />
for i,f in ipairs(forwarding) do<br />
if params.value[name].value[f] then<br />
supported = true<br />
fwd[f] = params.value[name].value[f].value<br />
if ((not oldparams.value[name] or not oldparams.value[name].value[f]) and (params.value[name].value[f].value ~= params.value[name].value[f].default)) or<br />
(oldparams.value[name] and oldparams.value[name].value[f] and (params.value[name].value[f].value ~= oldparams.value[name].value[f].value)) then<br />
change = true<br />
end<br />
end<br />
if change then<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
-- We'll notify whether it changed or not<br />
devices[o.value] = new<br />
end<br />
end<br />
end<br />
if supported then<br />
if not change and forwardsettings[new] then<br />
fwd = forwardsettings[new]<br />
elseif not change then<br />
-- This is a new extension, and the forwarding has not been set. We should check to see if there are any other devices with this extension<br />
local others = functions.getselectresponse("SELECT * FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."' AND device_id!='"..params.value.device_id.value.."'")<br />
if #others > 0 then<br />
-- Use the existing settings<br />
for i,f in ipairs(forwarding) do<br />
local v = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id='"..params.value[name].value[f].param_id.."' AND device_id='"..others[1].device_id.."' AND group_name='"..others[1].group_name.."' LIMIT 1")<br />
if #v > 0 then<br />
fwd[f] = v[1].value<br />
else<br />
fwd[f] = params.value[name].value[f].default<br />
end<br />
end<br />
end<br />
end<br />
if not change then<br />
for i,f in ipairs(forwarding) do<br />
params.value[name].value[f].value = fwd[f]<br />
end<br />
end<br />
forwardsettings[new] = fwd<br />
for i,f in ipairs(forwarding) do<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..params.value[name].value[f].param_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
if fwd[f] ~= params.value[name].value[f].default then<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..params.value[name].value[f].param_id.."', '"..tostring(fwd[f]).."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
end<br />
end<br />
end<br />
end<br />
elseif params.value[name] and oldparams.value[name] and params.value[name].value.extension.value ~= "" then<br />
if params.value[name].value.password.value ~= oldparams.value[name].value.password.value then<br />
-- Password changed - make any other registrations to this extension also change<br />
local pass = params.value[name].value.password.value<br />
if pass and pass ~= "" then<br />
APP.logevent("Password changed for "..new.." from "..oldparams.value[name].value.password.value.." to "..pass)<br />
else<br />
pass = generatepw()<br />
APP.logevent("Password cleared for "..new..", so set new random password "..pass)<br />
end<br />
passwords[new] = pass<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..password_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..password_id.."', '"..pass.."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
local u = kam.model.get_user(new)<br />
u.value.password.value = params.value[name].value.password.value<br />
u.value.password_confirm.value = params.value[name].value.password.value<br />
kam.model.update_user(u)<br />
-- Have to notify those other devices too<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
devices[o.value] = new<br />
end<br />
end<br />
local change = false<br />
local fwd = {}<br />
for i,f in ipairs(forwarding) do<br />
if params.value[name].value[f] and (not oldparams.value[name].value[f] or params.value[name].value[f].value ~= oldparams.value[name].value[f].value) then<br />
change = true<br />
break<br />
end<br />
end<br />
if change then<br />
-- Forwarding settings changed - make any other registrations to this extension also change<br />
for i,f in ipairs(forwarding) do<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..params.value[name].value[f].param_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
if params.value[name].value[f].value ~= params.value[name].value[f].default then<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..params.value[name].value[f].param_id.."', '"..tostring(params.value[name].value[f].value).."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
end<br />
end<br />
-- Have to notify those other devices too<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
devices[o.value] = new<br />
end<br />
end<br />
end<br />
end<br />
functions.runsqlcommand("COMMIT")<br />
<br />
-- If reg1 or freepstn changed, then need to change free-pstn in kam<br />
-- Since there can be multiple devices with the same reg1, we can't rely on params and oldparams<br />
-- Check both reg's<br />
--APP.logevent(session.serialize("params", params))<br />
local reg = {}<br />
if oldparams.value.reg1 and oldparams.value.reg1.value.extension and oldparams.value.reg1.value.extension.value ~= "" then<br />
reg[oldparams.value.reg1.value.extension.value] = false<br />
end<br />
if params.value.reg1 and params.value.reg1.value.extension and params.value.reg1.value.extension.value ~= "" then<br />
local pstn = false<br />
if params.value.routing and params.value.routing.value.freepstn then<br />
pstn = params.value.routing.value.freepstn.value<br />
end<br />
reg[params.value.reg1.value.extension.value] = pstn<br />
end<br />
<br />
APP.logevent("Looking at free-pstn")<br />
for r,f in pairs(reg) do<br />
-- if we're not sure, check provisioning database<br />
if not f then<br />
-- Most devices will have free-pstn due to class-of-service, but can be overridden, so this can get tricky<br />
-- Check all devices where reg1 extension = r, and see what the freepstn value is for each<br />
local others = functions.getselectresponse("SELECT CASE WHEN v.value IS NOT NULL THEN v.value WHEN g2p.value IS NOT NULL THEN g2p.value ELSE p.value END AS value "..<br />
"FROM (devices_to_classes d2t JOIN provisioning_classes t USING(class_id) JOIN classes_to_param_groups t2g USING (class_id) JOIN provisioning_groups g USING(group_id) "..<br />
"JOIN param_groups_to_params g2p USING(group_id) JOIN provisioning_params p USING(param_id)) LEFT JOIN provisioning_values v ON (d2t.device_id=v.device_id AND p.param_id=v.param_id AND g.name=v.group_name ) "..<br />
"WHERE p.name='freepstn' AND d2t.device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND group_name='reg1' AND value='"..r.."')")<br />
for i,o in ipairs(others) do<br />
-- Now check the freepstn value for each one<br />
if o.value == "true" then<br />
f = true<br />
break<br />
end<br />
end<br />
end<br />
-- Now, check the Kamailio group table<br />
local alreadythere = false<br />
local entries = kam.model.list_table_entries("grp")<br />
for i,e in ipairs(entries.value.entries.value) do<br />
if e.username == r then<br />
alreadythere = true<br />
if not f then<br />
APP.logevent("Removing free-pstn for "..r)<br />
-- Remove free-pstn from the old extension<br />
kam.model.delete_table_entry("grp", e.id)<br />
end<br />
break<br />
end<br />
end<br />
if f and not alreadythere then<br />
APP.logevent("Adding free-pstn for "..r)<br />
-- Add free-pstn to the new extension<br />
local e = kam.model.get_table_entry("grp")<br />
e.value.username.value = r<br />
e.value.domain.value = ""<br />
e.value.grp.value = "free-pstn"<br />
e.value.last_modified.value = os.date("%c")<br />
kam.model.create_table_entry(e)<br />
end<br />
end<br />
<br />
kam:destroy()<br />
<br />
-- If the mac address changed for Polycom with valid MAC (not blank or all 0's), we need to move the associated config files<br />
if oldparams.value.device and oldparams.value.device.value.mac and oldparams.value.device.value.mac.value ~= "" and params.value.device and params.value.device.value.mac and params.value.device.value.mac.value ~= oldparams.value.device.value.mac.value then<br />
if string.match(oldparams.value.device.label, "Polycom") and string.match(oldparams.value.device.value.mac.value, "[1-9A-F]") then<br />
local deletefiles = true<br />
if string.match(params.value.device.value.mac.value, "[1-9A-F]") then<br />
--APP.logevent("Moving files for "..oldparams.value.device.value.mac.value)<br />
deletefiles = false<br />
else<br />
--APP.logevent("Deleting files for "..oldparams.value.device.value.mac.value)<br />
end<br />
local path = root.."Polycom/"<br />
if posix.stat(path, "type") == "directory" then<br />
for d in posix.files(path) do<br />
if string.match(d, string.lower(oldparams.value.device.value.mac.value)) and posix.stat(path..d, "type") == "regular" then<br />
local newfile = string.gsub(d, string.lower(oldparams.value.device.value.mac.value), string.lower(params.value.device.value.mac.value))<br />
if deletefiles then<br />
--APP.logevent("deleting "..path..d)<br />
os.remove(path..d)<br />
else<br />
--APP.logevent("moving "..path..d.." to "..path..newfile)<br />
os.rename(path..d, path..newfile)<br />
end<br />
end<br />
end<br />
end<br />
end<br />
end<br />
<br />
-- Then, notify the phone to pull it's config<br />
-- Try to get a valid extension currently on the device<br />
local oldexten = ""<br />
for name,val in pairs(oldparams.value) do<br />
if string.match(name, "^reg") and val.value.extension and val.value.extension.value ~= "" then<br />
oldexten = val.value.extension.value<br />
break<br />
end<br />
end<br />
if params.value.device and params.value.device.value.mac and params.value.device.value.mac.value ~= "" then<br />
devices[params.value.device.value.mac.value] = oldexten<br />
end<br />
if oldparams.value.device and oldparams.value.device.value.mac and oldparams.value.device.value.mac.value ~= "" then<br />
devices[oldparams.value.device.value.mac.value] = oldexten<br />
end<br />
<br />
for name,value in pairs(devices) do<br />
notify_device(name,value)<br />
end<br />
</pre><br />
* Create /etc/provisioning/provisioning_db_script<br />
<pre><br />
#!/usr/bin/lua<br />
<br />
local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin "<br />
local creation_script = {<br />
-- Parameters<br />
"INSERT INTO provisioning_params VALUES(default, 'freepstn', 'boolean', 'Free PSTN Access', '', 'false', '200', '')",<br />
<br />
-- Parameter Groups<br />
"INSERT INTO provisioning_groups VALUES(default, 'routing', 'Free PSTN Access', '31')",<br />
"INSERT INTO provisioning_groups VALUES(default, 'routing', 'No Free PSTN Access', '32')",<br />
<br />
-- param_groups_to_params (group_id, param_id, value, editable)<br />
"INSERT INTO param_groups_to_params VALUES((SELECT group_id FROM provisioning_groups WHERE label='Free PSTN Access'), (SELECT param_id FROM provisioning_params WHERE name='freepstn'), 'true', false)",<br />
"INSERT INTO param_groups_to_params VALUES((SELECT group_id FROM provisioning_groups WHERE label='No Free PSTN Access'), (SELECT param_id FROM provisioning_params WHERE name='freepstn'), 'false', false)",<br />
<br />
-- Classes<br />
-- provisioning_class_groups (class_group_id, name, label, seq)<br />
"INSERT INTO provisioning_class_groups VALUES(default, 'routing', 'Routing', '3')",<br />
<br />
-- provisioning_classes (class_id, class_group_id, label, seq)<br />
"INSERT INTO provisioning_classes VALUES(default, (SELECT class_group_id FROM provisioning_class_groups WHERE name='routing'), 'Free PSTN Access', '1')",<br />
"INSERT INTO provisioning_classes VALUES(default, (SELECT class_group_id FROM provisioning_class_groups WHERE name='routing'), 'No Free PSTN Access', '2')",<br />
<br />
-- classes_to_param_groups (class_id, group_id)<br />
"INSERT INTO classes_to_param_groups VALUES((SELECT class_id FROM provisioning_classes WHERE label='Free PSTN Access'), (SELECT group_id FROM provisioning_groups WHERE label='Free PSTN Access'))",<br />
"INSERT INTO classes_to_param_groups VALUES((SELECT class_id FROM provisioning_classes WHERE label='No Free PSTN Access'), (SELECT group_id FROM provisioning_groups WHERE label='No Free PSTN Access'))",<br />
<br />
-- provisioning_options<br />
"INSERT INTO provisioning_options VALUES((SELECT param_id FROM provisioning_params WHERE name='polycomringtone'), 'Warble', '15', '15')",<br />
"INSERT INTO provisioning_options VALUES((SELECT param_id FROM provisioning_params WHERE name='polycomringtone'), 'Analog Ring', '16', '16')",<br />
}<br />
<br />
<br />
local f = io.popen("/usr/share/acf/www/cgi-bin/cli /provisioning/provisioning/getdevicevalues")<br />
print(f:read("*a"))<br />
f:close()<br />
for i,c in ipairs(creation_script) do<br />
print(path..'psql -U postgres -c "'..c..'" provisioning 2>&1')<br />
local f = io.popen(path..'psql -U postgres -c "'..c..'" provisioning 2>&1')<br />
print(f:read("*a"))<br />
f:close()<br />
end<br />
</pre><br />
* chmod 755 /etc/provisioning/provisioning_db_script<br />
* /etc/provisioning/provisioning_db_script<br />
* echo '* * * * * run-parts /etc/periodic/1min' >> /etc/crontabs/root<br />
* mkdir /etc/periodic/1min/<br />
* /etc/periodic/1min/notify_device<br />
<pre><br />
#!/usr/bin/lua<br />
<br />
-- Load libraries<br />
require("luasql.postgres")<br />
<br />
-- Set variables<br />
local DatabaseName = "provisioning"<br />
local DatabaseUser = "postgres"<br />
local DatabasePassword<br />
<br />
local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin "<br />
local env<br />
local con<br />
<br />
-- ################################################################################<br />
-- LOCAL FUNCTIONS<br />
local function assert (v, m)<br />
if not v then<br />
m = m or "Assertion failed!"<br />
error(m, 0)<br />
end<br />
return v, m<br />
end<br />
<br />
-- Escape special characters in sql statements<br />
local escape = function(sql)<br />
sql = sql or ""<br />
sql = string.gsub(sql, "'", "''")<br />
return string.gsub(sql, "\\", "\\\\")<br />
end<br />
<br />
local databaseconnect = function()<br />
if not con then<br />
-- create environment object<br />
env = assert (luasql.postgres())<br />
-- connect to data source<br />
local err<br />
con, err = assert(env:connect(DatabaseName, DatabaseUser, DatabasePassword))<br />
return true<br />
end<br />
return false<br />
end<br />
<br />
local databasedisconnect = function()<br />
if env then<br />
env:close()<br />
env = nil<br />
end<br />
if con then<br />
con:close()<br />
con = nil<br />
end<br />
end<br />
<br />
local getselectresponse = function(sql)<br />
local retval = {}<br />
local cur = assert (con:execute(sql))<br />
local row = cur:fetch ({}, "a")<br />
while row do<br />
local tmp = {}<br />
for name,val in pairs(row) do<br />
tmp[name] = val<br />
end<br />
retval[#retval + 1] = tmp<br />
row = cur:fetch (row, "a")<br />
end<br />
cur:close()<br />
return retval<br />
end<br />
<br />
databaseconnect()<br />
<br />
-- First, let's notify for the seasoned requests<br />
local reqs = getselectresponse("SELECT * FROM notify WHERE seasoned='true'")<br />
for i,r in ipairs(reqs) do<br />
os.execute("/etc/provisioning/notify_device "..r.ipaddr.." "..r.extension)<br />
end<br />
<br />
-- Then mark any others as seasoned<br />
assert(con:execute("DELETE FROM notify WHERE seasoned='true'"))<br />
assert(con:execute("UPDATE notify SET seasoned='true' WHERE seasoned='false'"))<br />
<br />
databasedisconnect()<br />
</pre><br />
* apk add lighttpd<br />
* rm /etc/lighttpd/lighttpd.conf<br />
* ln -s /etc/provisioning/lighttpd.sample.conf /etc/lighttpd/lighttpd.conf<br />
* /etc/lighttpd/mod_cgi.conf:<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "",<br />
"" => ""<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
* /etc/init.d/lighttpd start<br />
* rc-update add lighttpd<br />
<br />
* Customize provisioning:<br />
<pre><br />
Parameter Default Value<br />
registrar IP address or host name of SIP Router(s)<br />
digitmap Digit map for your phone system (See Polycom Digit Map Reference)<br />
digitmaptimeout Timeout in seconds corresponding to digitmap<br />
sntpserver 10.2.0.1 (DMVPN spoke node)<br />
timezone Timezone information for this location - see below<br />
musiconhold SIP uri of the music-on-hold service - moh@media.office.example.net<br />
adminpassword Administration password for advanced settings on phone (on-screen and web interface)<br />
</pre><br />
* apk fetch --stdout acf-provisioning-polycom | tar -C / -zx<br />
* Create a test Polycom device and boot it in the voice network to verify that it works<br />
<br />
== Install Kamailio ==<br />
* apk add kamailio kamailio-presence kamailio-pcre kamailio-postgres<br />
* /etc/init.d/kamailio start<br />
* rc-update add kamailio<br />
<br />
* FUTURE: POST CONFIG THAT USES SUBSCRIBER TABLE FOR AUTH<br />
<br />
= Install the SIP Media container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sipmedia -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sipmedia}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sipmedia/config, to reflect the network for the SIP Media container<br />
<br />
{{cat|/var/lib/lxc/sipmedia/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.sipmedia}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sipmedia}}<br />
<br />
== Enter the SIP Media container ==<br />
{{Cmd|lxc-console -n sipmedia}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.5<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
...<br />
<extension name="hold_music"> <br />
<condition field="destination_number" expression="^moh$"> <br />
<action application="answer"/> <br />
<action application="playback" data="$${hold_music}"/> <br />
</condition> <br />
</extension><br />
...<br />
<X-PRE-PROCESS cmd="set" data="hold_music=local_stream://default"/><br />
...<br />
FUTURE: ADD VOICEMAIL<br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
<br />
= Install the WiFi Web Proxy Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 172.17.48.1<br />
netmask 255.255.255.0<br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address 10.1.0.254<br />
netmask 255.255.255.252<br />
gateway 10.1.0.253<br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.1.0.131<br />
netmask 255.255.255.192<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10105
Small Office Services
2014-07-20T20:47:35Z
<p>Jbilyk: /* Install and Configure DHCP and DNS services */</p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
The assumption is made that the following VLANs and subnets are used as the DMVPN document did:<br />
<br />
{|class="wikitable"<br />
!'''Interface'''<br />
!'''Description'''<br />
!'''Subnet'''<br />
|-<br />
|bond0.3<br />
|Management<br />
|10.1.0.129/26<br />
|-<br />
|bond0.101<br />
|LAN<br />
|10.1.0.0/25<br />
|-<br />
|bond0.256<br />
|Internet from ISP1<br />
|Allocated from ISP<br />
|-<br />
|bond0.257<br />
|Internet from ISP2<br />
|Allocated from ISP<br />
|-<br />
|bond0.620<br />
|Transit between wifi proxy and dmvpn spoke node<br />
|10.1.0.252/30<br />
|-<br />
|bond0.701<br />
|WiFi clients (no access to DMVPN network)<br />
|172.17.48.0/24<br />
|-<br />
|bond0.1101<br />
|Voice<br />
|10.2.0.0/24<br />
|}<br />
<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.2<br />
netmask 255.255.255.192<br />
gateway 10.1.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$10.1.0.2",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth0<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth1<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth2<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Management VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.130<br />
netmask 255.255.255.192<br />
<br />
#WiFi VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address 172.16.48.2<br />
netmask 255.255.255.0<br />
<br />
#Voice VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.2.0.2<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
up ip address add 10.2.0.3/24 dev eth0<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers 10.2.0.1;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet 10.2.0.0 netmask 255.255.255.0<br />
{<br />
range "10.2.0.20 10.2.0.250";<br />
option domain-name-servers 10.2.0.2;<br />
option routers 10.2.0.1;<br />
option boot-server "http://10.2.0.4";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet 172.17.48.0 netmask 255.255.255.0<br />
{<br />
range "172.17.48.10 172.17.48.250";<br />
option routers 172.17.48.1;<br />
option domain-name-servers 172.17.48.1; <br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: 10.2.0.2<br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: 10.2.0.3<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.2.0.2 > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: 10.2.0.3<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A 10.2.0.3<br />
<br />
;A Records for SIP Devices<br />
sip IN A 10.2.0.4<br />
media IN A 10.2.0.5<br />
<br />
;NAPTR Records<br />
sip IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp.sip IN SRV 10 100 5060 sip<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.4<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'log_destination' variable to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
<br />
== Install acf-provisioning ==<br />
* vi /etc/kamailio/kamctlrc<br />
<pre><br />
SIP_DOMAIN=sip.office.example.net<br />
DBENGINE=PGSQL<br />
DBHOST=127.0.0.1<br />
DBNAME=openser<br />
DBRWUSER=openser<br />
DBRWPW="openser"<br />
DBROUSER=openserro<br />
DBROPW=openserro<br />
DBROOTUSER="postgres"<br />
</pre><br />
* yes | kamdbctl create openser<br />
* apk add acf-provisioning lua-socket lua-expat<br />
* Create /etc/provisioning/update_device_params.lua:<br />
<pre><br />
-- This is the script run after editing device params - basically only worried about extension and password<br />
local functions, params, oldparams = ...<br />
<br />
require("posix")<br />
require("luasql.postgres")<br />
<br />
local root = "/var/www/provisioning/htdocs/"<br />
local b62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"<br />
<br />
APP.logevent("got to update_device_params script")<br />
<br />
local function generatepw()<br />
-- generate a random 12-character alphanumeric string<br />
local file = io.open("/dev/urandom")<br />
local str = ""<br />
if file == nil then return nil end<br />
local size = 12<br />
while (size > 0 ) do<br />
local offset = (string.byte(file:read(1)) % 62) + 1<br />
str = str .. string.sub (b62, offset, offset)<br />
size = size - 1<br />
end<br />
return str<br />
end<br />
<br />
local function findip(mac)<br />
if not mac or mac == "" then<br />
return nil<br />
end<br />
local ipaddr = functions.getselectresponse("SELECT ip FROM provisioning_requests WHERE mac~*'"..mac.."'")<br />
if ipaddr and ipaddr[1] then<br />
return ipaddr[1].ip<br />
end<br />
end<br />
<br />
local function addfuturenotify(ipaddr, extension)<br />
local res, err = pcall(function()<br />
functions.runsqlcommand("DELETE FROM notify WHERE ipaddr='"..ipaddr.."' AND extension='"..extension.."'")<br />
end)<br />
if not res and err then<br />
if string.match(err, "relation \"(%S+)\" does not exist") then<br />
functions.runsqlcommand("CREATE TABLE notify (ipaddr text, extension text, seasoned boolean DEFAULT false)")<br />
else<br />
assert(res, err)<br />
end<br />
end<br />
-- if table missing, create it and delete again<br />
functions.runsqlcommand("INSERT INTO notify VALUES('"..ipaddr.."', '"..extension.."')")<br />
end<br />
<br />
local notify_device = function(mac, extension)<br />
local ipaddr = findip(mac)<br />
if ipaddr then<br />
APP.logevent("Notifying "..ipaddr.." to update for "..(mac or ""))<br />
os.execute("/etc/provisioning/notify_device "..ipaddr.." "..extension)<br />
addfuturenotify(ipaddr, extension)<br />
else<br />
APP.logevent("Warning - could not find IP address for "..(mac or ""))<br />
end<br />
end<br />
<br />
local kam = APP:new("kamailio/kamailio")<br />
<br />
-- A table of devices to notify to update<br />
local devices = {}<br />
<br />
-- First, we check the registration numbers / passwords to 1) set a random password (if necessary) 2) make sure password matches any other registrations to same extension 3) push changes (add / delete / or update) to Kam database<br />
-- Because this script also handles when device classes change, we have to consider that extensions are added / removed<br />
local regs = {}<br />
local forwarding = {"forwardnoanswerenable", "forwardnoanswer", "forwardbusyenable", "forwardbusy", "forwardallenable", "forwardall"}<br />
local forwardsettings = {} -- Collect forwarding settings<br />
local passwords = {} -- Collect old extension/password pairs<br />
for name,val in pairs(params.value) do<br />
if not regs[name] and string.match(name, "^reg") then<br />
regs[name] = true<br />
end<br />
end<br />
oldparams = oldparams or {value={}}<br />
for name,val in pairs(oldparams.value) do<br />
if string.match(name, "^reg") then<br />
if val.value and val.value.extension and val.value.password then<br />
passwords[val.value.extension.value] = val.value.password.value<br />
end<br />
if val.value and val.value.extension then<br />
local fwd = {}<br />
for i,f in ipairs(forwarding) do<br />
if val.value[f] then<br />
fwd[f] = val.value[f].value<br />
end<br />
end<br />
forwardsettings[val.value.extension.value] = fwd<br />
end<br />
if not regs[name] then<br />
regs[name] = true<br />
end<br />
end<br />
<br />
end<br />
local extension_id = params.value.reg1.value.extension.param_id<br />
local password_id = params.value.reg1.value.password.param_id<br />
functions.runsqlcommand("BEGIN TRANSACTION")<br />
for name,val in pairs(regs) do<br />
local new = ""<br />
local old = ""<br />
if params.value[name] then new = params.value[name].value.extension.value end<br />
if oldparams.value[name] then old = oldparams.value[name].value.extension.value end<br />
if new ~= old then<br />
-- Extension changed<br />
-- First, let's remove the stuff for the old extension<br />
if old ~= "" then<br />
local others = functions.getselectresponse("SELECT count(*) FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..old.."'")<br />
if others[1].count == "0" then<br />
APP.logevent("Removing old registration "..old)<br />
-- remove the registration<br />
kam.model.delete_user(old)<br />
end<br />
end<br />
-- Now, add the new extension<br />
if new ~= "" then<br />
local pass<br />
if params.value[name].value.password.value ~= "" and (not oldparams.value[name] or (oldparams.value[name].value.password.value ~= params.value[name].value.password.value)) then<br />
-- The password parameter was changed and not blank, so use it<br />
pass = params.value[name].value.password.value<br />
APP.logevent("Added a new registration "..new.." with specified password "..pass)<br />
-- There may be other devices with this extension<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
-- We'll notify whether it changed or not<br />
devices[o.value] = new<br />
end<br />
elseif passwords[new] then<br />
pass = passwords[new]<br />
APP.logevent("Added a new registration "..new.." with reused password "..pass)<br />
else<br />
local others = functions.getselectresponse("SELECT * FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."' AND device_id!='"..params.value.device_id.value.."'")<br />
-- If this is a new registration, use a new password<br />
if #others == 0 then<br />
pass = generatepw()<br />
APP.logevent("Added a new registration "..new.." with random password "..pass)<br />
else<br />
-- Use the old password<br />
local p = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id='"..password_id.."' AND device_id='"..others[1].device_id.."' AND group_name='"..others[1].group_name.."' LIMIT 1")<br />
pass = p[1].value<br />
APP.logevent("Added a new registration "..new.." with reused password "..pass)<br />
end<br />
end<br />
passwords[new] = pass<br />
params.value[name].value.password.value = pass<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..password_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..password_id.."', '"..pass.."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
local u = kam.model.get_user(new)<br />
if u.value.username.errtxt then<br />
-- Add this registration to Kam<br />
local u = kam.model.get_new_user()<br />
u.value.username.value = new<br />
u.value.password.value = pass<br />
u.value.password_confirm.value = pass<br />
kam.model.create_new_user(u)<br />
else<br />
u.value.password.value = pass<br />
u.value.password_confirm.value = pass<br />
kam.model.update_user(u)<br />
end<br />
-- Let's also look at the forwarding settings<br />
local change = false<br />
local supported = false<br />
local fwd = {}<br />
for i,f in ipairs(forwarding) do<br />
if params.value[name].value[f] then<br />
supported = true<br />
fwd[f] = params.value[name].value[f].value<br />
if ((not oldparams.value[name] or not oldparams.value[name].value[f]) and (params.value[name].value[f].value ~= params.value[name].value[f].default)) or<br />
(oldparams.value[name] and oldparams.value[name].value[f] and (params.value[name].value[f].value ~= oldparams.value[name].value[f].value)) then<br />
change = true<br />
end<br />
end<br />
if change then<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
-- We'll notify whether it changed or not<br />
devices[o.value] = new<br />
end<br />
end<br />
end<br />
if supported then<br />
if not change and forwardsettings[new] then<br />
fwd = forwardsettings[new]<br />
elseif not change then<br />
-- This is a new extension, and the forwarding has not been set. We should check to see if there are any other devices with this extension<br />
local others = functions.getselectresponse("SELECT * FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."' AND device_id!='"..params.value.device_id.value.."'")<br />
if #others > 0 then<br />
-- Use the existing settings<br />
for i,f in ipairs(forwarding) do<br />
local v = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id='"..params.value[name].value[f].param_id.."' AND device_id='"..others[1].device_id.."' AND group_name='"..others[1].group_name.."' LIMIT 1")<br />
if #v > 0 then<br />
fwd[f] = v[1].value<br />
else<br />
fwd[f] = params.value[name].value[f].default<br />
end<br />
end<br />
end<br />
end<br />
if not change then<br />
for i,f in ipairs(forwarding) do<br />
params.value[name].value[f].value = fwd[f]<br />
end<br />
end<br />
forwardsettings[new] = fwd<br />
for i,f in ipairs(forwarding) do<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..params.value[name].value[f].param_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
if fwd[f] ~= params.value[name].value[f].default then<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..params.value[name].value[f].param_id.."', '"..tostring(fwd[f]).."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
end<br />
end<br />
end<br />
end<br />
elseif params.value[name] and oldparams.value[name] and params.value[name].value.extension.value ~= "" then<br />
if params.value[name].value.password.value ~= oldparams.value[name].value.password.value then<br />
-- Password changed - make any other registrations to this extension also change<br />
local pass = params.value[name].value.password.value<br />
if pass and pass ~= "" then<br />
APP.logevent("Password changed for "..new.." from "..oldparams.value[name].value.password.value.." to "..pass)<br />
else<br />
pass = generatepw()<br />
APP.logevent("Password cleared for "..new..", so set new random password "..pass)<br />
end<br />
passwords[new] = pass<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..password_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..password_id.."', '"..pass.."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
local u = kam.model.get_user(new)<br />
u.value.password.value = params.value[name].value.password.value<br />
u.value.password_confirm.value = params.value[name].value.password.value<br />
kam.model.update_user(u)<br />
-- Have to notify those other devices too<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
devices[o.value] = new<br />
end<br />
end<br />
local change = false<br />
local fwd = {}<br />
for i,f in ipairs(forwarding) do<br />
if params.value[name].value[f] and (not oldparams.value[name].value[f] or params.value[name].value[f].value ~= oldparams.value[name].value[f].value) then<br />
change = true<br />
break<br />
end<br />
end<br />
if change then<br />
-- Forwarding settings changed - make any other registrations to this extension also change<br />
for i,f in ipairs(forwarding) do<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..params.value[name].value[f].param_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
if params.value[name].value[f].value ~= params.value[name].value[f].default then<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..params.value[name].value[f].param_id.."', '"..tostring(params.value[name].value[f].value).."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
end<br />
end<br />
-- Have to notify those other devices too<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
devices[o.value] = new<br />
end<br />
end<br />
end<br />
end<br />
functions.runsqlcommand("COMMIT")<br />
<br />
-- If reg1 or freepstn changed, then need to change free-pstn in kam<br />
-- Since there can be multiple devices with the same reg1, we can't rely on params and oldparams<br />
-- Check both reg's<br />
--APP.logevent(session.serialize("params", params))<br />
local reg = {}<br />
if oldparams.value.reg1 and oldparams.value.reg1.value.extension and oldparams.value.reg1.value.extension.value ~= "" then<br />
reg[oldparams.value.reg1.value.extension.value] = false<br />
end<br />
if params.value.reg1 and params.value.reg1.value.extension and params.value.reg1.value.extension.value ~= "" then<br />
local pstn = false<br />
if params.value.routing and params.value.routing.value.freepstn then<br />
pstn = params.value.routing.value.freepstn.value<br />
end<br />
reg[params.value.reg1.value.extension.value] = pstn<br />
end<br />
<br />
APP.logevent("Looking at free-pstn")<br />
for r,f in pairs(reg) do<br />
-- if we're not sure, check provisioning database<br />
if not f then<br />
-- Most devices will have free-pstn due to class-of-service, but can be overridden, so this can get tricky<br />
-- Check all devices where reg1 extension = r, and see what the freepstn value is for each<br />
local others = functions.getselectresponse("SELECT CASE WHEN v.value IS NOT NULL THEN v.value WHEN g2p.value IS NOT NULL THEN g2p.value ELSE p.value END AS value "..<br />
"FROM (devices_to_classes d2t JOIN provisioning_classes t USING(class_id) JOIN classes_to_param_groups t2g USING (class_id) JOIN provisioning_groups g USING(group_id) "..<br />
"JOIN param_groups_to_params g2p USING(group_id) JOIN provisioning_params p USING(param_id)) LEFT JOIN provisioning_values v ON (d2t.device_id=v.device_id AND p.param_id=v.param_id AND g.name=v.group_name ) "..<br />
"WHERE p.name='freepstn' AND d2t.device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND group_name='reg1' AND value='"..r.."')")<br />
for i,o in ipairs(others) do<br />
-- Now check the freepstn value for each one<br />
if o.value == "true" then<br />
f = true<br />
break<br />
end<br />
end<br />
end<br />
-- Now, check the Kamailio group table<br />
local alreadythere = false<br />
local entries = kam.model.list_table_entries("grp")<br />
for i,e in ipairs(entries.value.entries.value) do<br />
if e.username == r then<br />
alreadythere = true<br />
if not f then<br />
APP.logevent("Removing free-pstn for "..r)<br />
-- Remove free-pstn from the old extension<br />
kam.model.delete_table_entry("grp", e.id)<br />
end<br />
break<br />
end<br />
end<br />
if f and not alreadythere then<br />
APP.logevent("Adding free-pstn for "..r)<br />
-- Add free-pstn to the new extension<br />
local e = kam.model.get_table_entry("grp")<br />
e.value.username.value = r<br />
e.value.domain.value = ""<br />
e.value.grp.value = "free-pstn"<br />
e.value.last_modified.value = os.date("%c")<br />
kam.model.create_table_entry(e)<br />
end<br />
end<br />
<br />
kam:destroy()<br />
<br />
-- If the mac address changed for Polycom with valid MAC (not blank or all 0's), we need to move the associated config files<br />
if oldparams.value.device and oldparams.value.device.value.mac and oldparams.value.device.value.mac.value ~= "" and params.value.device and params.value.device.value.mac and params.value.device.value.mac.value ~= oldparams.value.device.value.mac.value then<br />
if string.match(oldparams.value.device.label, "Polycom") and string.match(oldparams.value.device.value.mac.value, "[1-9A-F]") then<br />
local deletefiles = true<br />
if string.match(params.value.device.value.mac.value, "[1-9A-F]") then<br />
--APP.logevent("Moving files for "..oldparams.value.device.value.mac.value)<br />
deletefiles = false<br />
else<br />
--APP.logevent("Deleting files for "..oldparams.value.device.value.mac.value)<br />
end<br />
local path = root.."Polycom/"<br />
if posix.stat(path, "type") == "directory" then<br />
for d in posix.files(path) do<br />
if string.match(d, string.lower(oldparams.value.device.value.mac.value)) and posix.stat(path..d, "type") == "regular" then<br />
local newfile = string.gsub(d, string.lower(oldparams.value.device.value.mac.value), string.lower(params.value.device.value.mac.value))<br />
if deletefiles then<br />
--APP.logevent("deleting "..path..d)<br />
os.remove(path..d)<br />
else<br />
--APP.logevent("moving "..path..d.." to "..path..newfile)<br />
os.rename(path..d, path..newfile)<br />
end<br />
end<br />
end<br />
end<br />
end<br />
end<br />
<br />
-- Then, notify the phone to pull it's config<br />
-- Try to get a valid extension currently on the device<br />
local oldexten = ""<br />
for name,val in pairs(oldparams.value) do<br />
if string.match(name, "^reg") and val.value.extension and val.value.extension.value ~= "" then<br />
oldexten = val.value.extension.value<br />
break<br />
end<br />
end<br />
if params.value.device and params.value.device.value.mac and params.value.device.value.mac.value ~= "" then<br />
devices[params.value.device.value.mac.value] = oldexten<br />
end<br />
if oldparams.value.device and oldparams.value.device.value.mac and oldparams.value.device.value.mac.value ~= "" then<br />
devices[oldparams.value.device.value.mac.value] = oldexten<br />
end<br />
<br />
for name,value in pairs(devices) do<br />
notify_device(name,value)<br />
end<br />
</pre><br />
* Create /etc/provisioning/provisioning_db_script<br />
<pre><br />
#!/usr/bin/lua<br />
<br />
local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin "<br />
local creation_script = {<br />
-- Parameters<br />
"INSERT INTO provisioning_params VALUES(default, 'freepstn', 'boolean', 'Free PSTN Access', '', 'false', '200', '')",<br />
<br />
-- Parameter Groups<br />
"INSERT INTO provisioning_groups VALUES(default, 'routing', 'Free PSTN Access', '31')",<br />
"INSERT INTO provisioning_groups VALUES(default, 'routing', 'No Free PSTN Access', '32')",<br />
<br />
-- param_groups_to_params (group_id, param_id, value, editable)<br />
"INSERT INTO param_groups_to_params VALUES((SELECT group_id FROM provisioning_groups WHERE label='Free PSTN Access'), (SELECT param_id FROM provisioning_params WHERE name='freepstn'), 'true', false)",<br />
"INSERT INTO param_groups_to_params VALUES((SELECT group_id FROM provisioning_groups WHERE label='No Free PSTN Access'), (SELECT param_id FROM provisioning_params WHERE name='freepstn'), 'false', false)",<br />
<br />
-- Classes<br />
-- provisioning_class_groups (class_group_id, name, label, seq)<br />
"INSERT INTO provisioning_class_groups VALUES(default, 'routing', 'Routing', '3')",<br />
<br />
-- provisioning_classes (class_id, class_group_id, label, seq)<br />
"INSERT INTO provisioning_classes VALUES(default, (SELECT class_group_id FROM provisioning_class_groups WHERE name='routing'), 'Free PSTN Access', '1')",<br />
"INSERT INTO provisioning_classes VALUES(default, (SELECT class_group_id FROM provisioning_class_groups WHERE name='routing'), 'No Free PSTN Access', '2')",<br />
<br />
-- classes_to_param_groups (class_id, group_id)<br />
"INSERT INTO classes_to_param_groups VALUES((SELECT class_id FROM provisioning_classes WHERE label='Free PSTN Access'), (SELECT group_id FROM provisioning_groups WHERE label='Free PSTN Access'))",<br />
"INSERT INTO classes_to_param_groups VALUES((SELECT class_id FROM provisioning_classes WHERE label='No Free PSTN Access'), (SELECT group_id FROM provisioning_groups WHERE label='No Free PSTN Access'))",<br />
<br />
-- provisioning_options<br />
"INSERT INTO provisioning_options VALUES((SELECT param_id FROM provisioning_params WHERE name='polycomringtone'), 'Warble', '15', '15')",<br />
"INSERT INTO provisioning_options VALUES((SELECT param_id FROM provisioning_params WHERE name='polycomringtone'), 'Analog Ring', '16', '16')",<br />
}<br />
<br />
<br />
local f = io.popen("/usr/share/acf/www/cgi-bin/cli /provisioning/provisioning/getdevicevalues")<br />
print(f:read("*a"))<br />
f:close()<br />
for i,c in ipairs(creation_script) do<br />
print(path..'psql -U postgres -c "'..c..'" provisioning 2>&1')<br />
local f = io.popen(path..'psql -U postgres -c "'..c..'" provisioning 2>&1')<br />
print(f:read("*a"))<br />
f:close()<br />
end<br />
</pre><br />
* chmod 755 /etc/provisioning/provisioning_db_script<br />
* /etc/provisioning/provisioning_db_script<br />
* echo '* * * * * run-parts /etc/periodic/1min' >> /etc/crontabs/root<br />
* mkdir /etc/periodic/1min/<br />
* /etc/periodic/1min/notify_device<br />
<pre><br />
#!/usr/bin/lua<br />
<br />
-- Load libraries<br />
require("luasql.postgres")<br />
<br />
-- Set variables<br />
local DatabaseName = "provisioning"<br />
local DatabaseUser = "postgres"<br />
local DatabasePassword<br />
<br />
local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin "<br />
local env<br />
local con<br />
<br />
-- ################################################################################<br />
-- LOCAL FUNCTIONS<br />
local function assert (v, m)<br />
if not v then<br />
m = m or "Assertion failed!"<br />
error(m, 0)<br />
end<br />
return v, m<br />
end<br />
<br />
-- Escape special characters in sql statements<br />
local escape = function(sql)<br />
sql = sql or ""<br />
sql = string.gsub(sql, "'", "''")<br />
return string.gsub(sql, "\\", "\\\\")<br />
end<br />
<br />
local databaseconnect = function()<br />
if not con then<br />
-- create environment object<br />
env = assert (luasql.postgres())<br />
-- connect to data source<br />
local err<br />
con, err = assert(env:connect(DatabaseName, DatabaseUser, DatabasePassword))<br />
return true<br />
end<br />
return false<br />
end<br />
<br />
local databasedisconnect = function()<br />
if env then<br />
env:close()<br />
env = nil<br />
end<br />
if con then<br />
con:close()<br />
con = nil<br />
end<br />
end<br />
<br />
local getselectresponse = function(sql)<br />
local retval = {}<br />
local cur = assert (con:execute(sql))<br />
local row = cur:fetch ({}, "a")<br />
while row do<br />
local tmp = {}<br />
for name,val in pairs(row) do<br />
tmp[name] = val<br />
end<br />
retval[#retval + 1] = tmp<br />
row = cur:fetch (row, "a")<br />
end<br />
cur:close()<br />
return retval<br />
end<br />
<br />
databaseconnect()<br />
<br />
-- First, let's notify for the seasoned requests<br />
local reqs = getselectresponse("SELECT * FROM notify WHERE seasoned='true'")<br />
for i,r in ipairs(reqs) do<br />
os.execute("/etc/provisioning/notify_device "..r.ipaddr.." "..r.extension)<br />
end<br />
<br />
-- Then mark any others as seasoned<br />
assert(con:execute("DELETE FROM notify WHERE seasoned='true'"))<br />
assert(con:execute("UPDATE notify SET seasoned='true' WHERE seasoned='false'"))<br />
<br />
databasedisconnect()<br />
</pre><br />
* apk add lighttpd<br />
* rm /etc/lighttpd/lighttpd.conf<br />
* ln -s /etc/provisioning/lighttpd.sample.conf /etc/lighttpd/lighttpd.conf<br />
* /etc/lighttpd/mod_cgi.conf:<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "",<br />
"" => ""<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
* /etc/init.d/lighttpd start<br />
* rc-update add lighttpd<br />
<br />
* Customize provisioning:<br />
<pre><br />
Parameter Default Value<br />
registrar IP address or host name of SIP Router(s)<br />
digitmap Digit map for your phone system (See Polycom Digit Map Reference)<br />
digitmaptimeout Timeout in seconds corresponding to digitmap<br />
sntpserver 10.2.0.1 (DMVPN spoke node)<br />
timezone Timezone information for this location - see below<br />
musiconhold SIP uri of the music-on-hold service - moh@media.office.example.net<br />
adminpassword Administration password for advanced settings on phone (on-screen and web interface)<br />
</pre><br />
* apk fetch --stdout acf-provisioning-polycom | tar -C / -zx<br />
* Create a test Polycom device and boot it in the voice network to verify that it works<br />
<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the SIP Media container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sipmedia -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sipmedia}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sipmedia/config, to reflect the network for the SIP Media container<br />
<br />
{{cat|/var/lib/lxc/sipmedia/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.sipmedia}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sipmedia}}<br />
<br />
== Enter the SIP Media container ==<br />
{{Cmd|lxc-console -n sipmedia}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.5<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
...<br />
<extension name="hold_music"> <br />
<condition field="destination_number" expression="^moh$"> <br />
<action application="answer"/> <br />
<action application="playback" data="$${hold_music}"/> <br />
</condition> <br />
</extension><br />
...<br />
<X-PRE-PROCESS cmd="set" data="hold_music=local_stream://default"/><br />
...<br />
FUTURE: ADD VOICEMAIL<br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
<br />
= Install the WiFi Web Proxy Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 172.17.48.1<br />
netmask 255.255.255.0<br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address 10.1.0.254<br />
netmask 255.255.255.252<br />
gateway 10.1.0.253<br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.1.0.131<br />
netmask 255.255.255.192<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10104
Small Office Services
2014-07-20T20:45:36Z
<p>Jbilyk: /* Install and Configure Freeswitch */</p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
The assumption is made that the following VLANs and subnets are used as the DMVPN document did:<br />
<br />
{|class="wikitable"<br />
!'''Interface'''<br />
!'''Description'''<br />
!'''Subnet'''<br />
|-<br />
|bond0.3<br />
|Management<br />
|10.1.0.129/26<br />
|-<br />
|bond0.101<br />
|LAN<br />
|10.1.0.0/25<br />
|-<br />
|bond0.256<br />
|Internet from ISP1<br />
|Allocated from ISP<br />
|-<br />
|bond0.257<br />
|Internet from ISP2<br />
|Allocated from ISP<br />
|-<br />
|bond0.620<br />
|Transit between wifi proxy and dmvpn spoke node<br />
|10.1.0.252/30<br />
|-<br />
|bond0.701<br />
|WiFi clients (no access to DMVPN network)<br />
|172.17.48.0/24<br />
|-<br />
|bond0.1101<br />
|Voice<br />
|10.2.0.0/24<br />
|}<br />
<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.2<br />
netmask 255.255.255.192<br />
gateway 10.1.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$10.1.0.2",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth0<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth1<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth2<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Management VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.130<br />
netmask 255.255.255.192<br />
<br />
#WiFi VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address 172.16.48.2<br />
netmask 255.255.255.0<br />
<br />
#Voice VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.2.0.2<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
up ip address add 10.2.0.3/24 dev eth0<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers 10.2.0.1;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet 10.2.0.0 netmask 255.255.255.0<br />
{<br />
range "10.2.0.20 10.2.0.250";<br />
option domain-name-servers 10.2.0.2;<br />
option routers 10.2.0.1;<br />
option boot-server "http://10.2.0.4";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet 172.17.48.0 netmask 255.255.255.0<br />
{<br />
range "172.17.48.10 172.17.48.250";<br />
option routers 172.17.48.1;<br />
option domain-name-servers 172.17.48.1; <br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: 10.2.0.2<br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: 10.2.0.3<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.2.0.2 > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: 10.2.0.3<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A 10.2.0.3<br />
<br />
;A Records for SIP Devices<br />
sip IN A 10.2.0.4<br />
media IN A 10.2.0.5<br />
<br />
;NAPTR Records<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.media.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp.sip IN SRV 10 1 5060 sip<br />
_sip._udp.media IN SRV 10 1 5060 media<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.4<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'log_destination' variable to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
<br />
== Install acf-provisioning ==<br />
* vi /etc/kamailio/kamctlrc<br />
<pre><br />
SIP_DOMAIN=sip.office.example.net<br />
DBENGINE=PGSQL<br />
DBHOST=127.0.0.1<br />
DBNAME=openser<br />
DBRWUSER=openser<br />
DBRWPW="openser"<br />
DBROUSER=openserro<br />
DBROPW=openserro<br />
DBROOTUSER="postgres"<br />
</pre><br />
* yes | kamdbctl create openser<br />
* apk add acf-provisioning lua-socket lua-expat<br />
* Create /etc/provisioning/update_device_params.lua:<br />
<pre><br />
-- This is the script run after editing device params - basically only worried about extension and password<br />
local functions, params, oldparams = ...<br />
<br />
require("posix")<br />
require("luasql.postgres")<br />
<br />
local root = "/var/www/provisioning/htdocs/"<br />
local b62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"<br />
<br />
APP.logevent("got to update_device_params script")<br />
<br />
local function generatepw()<br />
-- generate a random 12-character alphanumeric string<br />
local file = io.open("/dev/urandom")<br />
local str = ""<br />
if file == nil then return nil end<br />
local size = 12<br />
while (size > 0 ) do<br />
local offset = (string.byte(file:read(1)) % 62) + 1<br />
str = str .. string.sub (b62, offset, offset)<br />
size = size - 1<br />
end<br />
return str<br />
end<br />
<br />
local function findip(mac)<br />
if not mac or mac == "" then<br />
return nil<br />
end<br />
local ipaddr = functions.getselectresponse("SELECT ip FROM provisioning_requests WHERE mac~*'"..mac.."'")<br />
if ipaddr and ipaddr[1] then<br />
return ipaddr[1].ip<br />
end<br />
end<br />
<br />
local function addfuturenotify(ipaddr, extension)<br />
local res, err = pcall(function()<br />
functions.runsqlcommand("DELETE FROM notify WHERE ipaddr='"..ipaddr.."' AND extension='"..extension.."'")<br />
end)<br />
if not res and err then<br />
if string.match(err, "relation \"(%S+)\" does not exist") then<br />
functions.runsqlcommand("CREATE TABLE notify (ipaddr text, extension text, seasoned boolean DEFAULT false)")<br />
else<br />
assert(res, err)<br />
end<br />
end<br />
-- if table missing, create it and delete again<br />
functions.runsqlcommand("INSERT INTO notify VALUES('"..ipaddr.."', '"..extension.."')")<br />
end<br />
<br />
local notify_device = function(mac, extension)<br />
local ipaddr = findip(mac)<br />
if ipaddr then<br />
APP.logevent("Notifying "..ipaddr.." to update for "..(mac or ""))<br />
os.execute("/etc/provisioning/notify_device "..ipaddr.." "..extension)<br />
addfuturenotify(ipaddr, extension)<br />
else<br />
APP.logevent("Warning - could not find IP address for "..(mac or ""))<br />
end<br />
end<br />
<br />
local kam = APP:new("kamailio/kamailio")<br />
<br />
-- A table of devices to notify to update<br />
local devices = {}<br />
<br />
-- First, we check the registration numbers / passwords to 1) set a random password (if necessary) 2) make sure password matches any other registrations to same extension 3) push changes (add / delete / or update) to Kam database<br />
-- Because this script also handles when device classes change, we have to consider that extensions are added / removed<br />
local regs = {}<br />
local forwarding = {"forwardnoanswerenable", "forwardnoanswer", "forwardbusyenable", "forwardbusy", "forwardallenable", "forwardall"}<br />
local forwardsettings = {} -- Collect forwarding settings<br />
local passwords = {} -- Collect old extension/password pairs<br />
for name,val in pairs(params.value) do<br />
if not regs[name] and string.match(name, "^reg") then<br />
regs[name] = true<br />
end<br />
end<br />
oldparams = oldparams or {value={}}<br />
for name,val in pairs(oldparams.value) do<br />
if string.match(name, "^reg") then<br />
if val.value and val.value.extension and val.value.password then<br />
passwords[val.value.extension.value] = val.value.password.value<br />
end<br />
if val.value and val.value.extension then<br />
local fwd = {}<br />
for i,f in ipairs(forwarding) do<br />
if val.value[f] then<br />
fwd[f] = val.value[f].value<br />
end<br />
end<br />
forwardsettings[val.value.extension.value] = fwd<br />
end<br />
if not regs[name] then<br />
regs[name] = true<br />
end<br />
end<br />
<br />
end<br />
local extension_id = params.value.reg1.value.extension.param_id<br />
local password_id = params.value.reg1.value.password.param_id<br />
functions.runsqlcommand("BEGIN TRANSACTION")<br />
for name,val in pairs(regs) do<br />
local new = ""<br />
local old = ""<br />
if params.value[name] then new = params.value[name].value.extension.value end<br />
if oldparams.value[name] then old = oldparams.value[name].value.extension.value end<br />
if new ~= old then<br />
-- Extension changed<br />
-- First, let's remove the stuff for the old extension<br />
if old ~= "" then<br />
local others = functions.getselectresponse("SELECT count(*) FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..old.."'")<br />
if others[1].count == "0" then<br />
APP.logevent("Removing old registration "..old)<br />
-- remove the registration<br />
kam.model.delete_user(old)<br />
end<br />
end<br />
-- Now, add the new extension<br />
if new ~= "" then<br />
local pass<br />
if params.value[name].value.password.value ~= "" and (not oldparams.value[name] or (oldparams.value[name].value.password.value ~= params.value[name].value.password.value)) then<br />
-- The password parameter was changed and not blank, so use it<br />
pass = params.value[name].value.password.value<br />
APP.logevent("Added a new registration "..new.." with specified password "..pass)<br />
-- There may be other devices with this extension<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
-- We'll notify whether it changed or not<br />
devices[o.value] = new<br />
end<br />
elseif passwords[new] then<br />
pass = passwords[new]<br />
APP.logevent("Added a new registration "..new.." with reused password "..pass)<br />
else<br />
local others = functions.getselectresponse("SELECT * FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."' AND device_id!='"..params.value.device_id.value.."'")<br />
-- If this is a new registration, use a new password<br />
if #others == 0 then<br />
pass = generatepw()<br />
APP.logevent("Added a new registration "..new.." with random password "..pass)<br />
else<br />
-- Use the old password<br />
local p = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id='"..password_id.."' AND device_id='"..others[1].device_id.."' AND group_name='"..others[1].group_name.."' LIMIT 1")<br />
pass = p[1].value<br />
APP.logevent("Added a new registration "..new.." with reused password "..pass)<br />
end<br />
end<br />
passwords[new] = pass<br />
params.value[name].value.password.value = pass<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..password_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..password_id.."', '"..pass.."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
local u = kam.model.get_user(new)<br />
if u.value.username.errtxt then<br />
-- Add this registration to Kam<br />
local u = kam.model.get_new_user()<br />
u.value.username.value = new<br />
u.value.password.value = pass<br />
u.value.password_confirm.value = pass<br />
kam.model.create_new_user(u)<br />
else<br />
u.value.password.value = pass<br />
u.value.password_confirm.value = pass<br />
kam.model.update_user(u)<br />
end<br />
-- Let's also look at the forwarding settings<br />
local change = false<br />
local supported = false<br />
local fwd = {}<br />
for i,f in ipairs(forwarding) do<br />
if params.value[name].value[f] then<br />
supported = true<br />
fwd[f] = params.value[name].value[f].value<br />
if ((not oldparams.value[name] or not oldparams.value[name].value[f]) and (params.value[name].value[f].value ~= params.value[name].value[f].default)) or<br />
(oldparams.value[name] and oldparams.value[name].value[f] and (params.value[name].value[f].value ~= oldparams.value[name].value[f].value)) then<br />
change = true<br />
end<br />
end<br />
if change then<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
-- We'll notify whether it changed or not<br />
devices[o.value] = new<br />
end<br />
end<br />
end<br />
if supported then<br />
if not change and forwardsettings[new] then<br />
fwd = forwardsettings[new]<br />
elseif not change then<br />
-- This is a new extension, and the forwarding has not been set. We should check to see if there are any other devices with this extension<br />
local others = functions.getselectresponse("SELECT * FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."' AND device_id!='"..params.value.device_id.value.."'")<br />
if #others > 0 then<br />
-- Use the existing settings<br />
for i,f in ipairs(forwarding) do<br />
local v = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id='"..params.value[name].value[f].param_id.."' AND device_id='"..others[1].device_id.."' AND group_name='"..others[1].group_name.."' LIMIT 1")<br />
if #v > 0 then<br />
fwd[f] = v[1].value<br />
else<br />
fwd[f] = params.value[name].value[f].default<br />
end<br />
end<br />
end<br />
end<br />
if not change then<br />
for i,f in ipairs(forwarding) do<br />
params.value[name].value[f].value = fwd[f]<br />
end<br />
end<br />
forwardsettings[new] = fwd<br />
for i,f in ipairs(forwarding) do<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..params.value[name].value[f].param_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
if fwd[f] ~= params.value[name].value[f].default then<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..params.value[name].value[f].param_id.."', '"..tostring(fwd[f]).."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
end<br />
end<br />
end<br />
end<br />
elseif params.value[name] and oldparams.value[name] and params.value[name].value.extension.value ~= "" then<br />
if params.value[name].value.password.value ~= oldparams.value[name].value.password.value then<br />
-- Password changed - make any other registrations to this extension also change<br />
local pass = params.value[name].value.password.value<br />
if pass and pass ~= "" then<br />
APP.logevent("Password changed for "..new.." from "..oldparams.value[name].value.password.value.." to "..pass)<br />
else<br />
pass = generatepw()<br />
APP.logevent("Password cleared for "..new..", so set new random password "..pass)<br />
end<br />
passwords[new] = pass<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..password_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..password_id.."', '"..pass.."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
local u = kam.model.get_user(new)<br />
u.value.password.value = params.value[name].value.password.value<br />
u.value.password_confirm.value = params.value[name].value.password.value<br />
kam.model.update_user(u)<br />
-- Have to notify those other devices too<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
devices[o.value] = new<br />
end<br />
end<br />
local change = false<br />
local fwd = {}<br />
for i,f in ipairs(forwarding) do<br />
if params.value[name].value[f] and (not oldparams.value[name].value[f] or params.value[name].value[f].value ~= oldparams.value[name].value[f].value) then<br />
change = true<br />
break<br />
end<br />
end<br />
if change then<br />
-- Forwarding settings changed - make any other registrations to this extension also change<br />
for i,f in ipairs(forwarding) do<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..params.value[name].value[f].param_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
if params.value[name].value[f].value ~= params.value[name].value[f].default then<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..params.value[name].value[f].param_id.."', '"..tostring(params.value[name].value[f].value).."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
end<br />
end<br />
-- Have to notify those other devices too<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
devices[o.value] = new<br />
end<br />
end<br />
end<br />
end<br />
functions.runsqlcommand("COMMIT")<br />
<br />
-- If reg1 or freepstn changed, then need to change free-pstn in kam<br />
-- Since there can be multiple devices with the same reg1, we can't rely on params and oldparams<br />
-- Check both reg's<br />
--APP.logevent(session.serialize("params", params))<br />
local reg = {}<br />
if oldparams.value.reg1 and oldparams.value.reg1.value.extension and oldparams.value.reg1.value.extension.value ~= "" then<br />
reg[oldparams.value.reg1.value.extension.value] = false<br />
end<br />
if params.value.reg1 and params.value.reg1.value.extension and params.value.reg1.value.extension.value ~= "" then<br />
local pstn = false<br />
if params.value.routing and params.value.routing.value.freepstn then<br />
pstn = params.value.routing.value.freepstn.value<br />
end<br />
reg[params.value.reg1.value.extension.value] = pstn<br />
end<br />
<br />
APP.logevent("Looking at free-pstn")<br />
for r,f in pairs(reg) do<br />
-- if we're not sure, check provisioning database<br />
if not f then<br />
-- Most devices will have free-pstn due to class-of-service, but can be overridden, so this can get tricky<br />
-- Check all devices where reg1 extension = r, and see what the freepstn value is for each<br />
local others = functions.getselectresponse("SELECT CASE WHEN v.value IS NOT NULL THEN v.value WHEN g2p.value IS NOT NULL THEN g2p.value ELSE p.value END AS value "..<br />
"FROM (devices_to_classes d2t JOIN provisioning_classes t USING(class_id) JOIN classes_to_param_groups t2g USING (class_id) JOIN provisioning_groups g USING(group_id) "..<br />
"JOIN param_groups_to_params g2p USING(group_id) JOIN provisioning_params p USING(param_id)) LEFT JOIN provisioning_values v ON (d2t.device_id=v.device_id AND p.param_id=v.param_id AND g.name=v.group_name ) "..<br />
"WHERE p.name='freepstn' AND d2t.device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND group_name='reg1' AND value='"..r.."')")<br />
for i,o in ipairs(others) do<br />
-- Now check the freepstn value for each one<br />
if o.value == "true" then<br />
f = true<br />
break<br />
end<br />
end<br />
end<br />
-- Now, check the Kamailio group table<br />
local alreadythere = false<br />
local entries = kam.model.list_table_entries("grp")<br />
for i,e in ipairs(entries.value.entries.value) do<br />
if e.username == r then<br />
alreadythere = true<br />
if not f then<br />
APP.logevent("Removing free-pstn for "..r)<br />
-- Remove free-pstn from the old extension<br />
kam.model.delete_table_entry("grp", e.id)<br />
end<br />
break<br />
end<br />
end<br />
if f and not alreadythere then<br />
APP.logevent("Adding free-pstn for "..r)<br />
-- Add free-pstn to the new extension<br />
local e = kam.model.get_table_entry("grp")<br />
e.value.username.value = r<br />
e.value.domain.value = ""<br />
e.value.grp.value = "free-pstn"<br />
e.value.last_modified.value = os.date("%c")<br />
kam.model.create_table_entry(e)<br />
end<br />
end<br />
<br />
kam:destroy()<br />
<br />
-- If the mac address changed for Polycom with valid MAC (not blank or all 0's), we need to move the associated config files<br />
if oldparams.value.device and oldparams.value.device.value.mac and oldparams.value.device.value.mac.value ~= "" and params.value.device and params.value.device.value.mac and params.value.device.value.mac.value ~= oldparams.value.device.value.mac.value then<br />
if string.match(oldparams.value.device.label, "Polycom") and string.match(oldparams.value.device.value.mac.value, "[1-9A-F]") then<br />
local deletefiles = true<br />
if string.match(params.value.device.value.mac.value, "[1-9A-F]") then<br />
--APP.logevent("Moving files for "..oldparams.value.device.value.mac.value)<br />
deletefiles = false<br />
else<br />
--APP.logevent("Deleting files for "..oldparams.value.device.value.mac.value)<br />
end<br />
local path = root.."Polycom/"<br />
if posix.stat(path, "type") == "directory" then<br />
for d in posix.files(path) do<br />
if string.match(d, string.lower(oldparams.value.device.value.mac.value)) and posix.stat(path..d, "type") == "regular" then<br />
local newfile = string.gsub(d, string.lower(oldparams.value.device.value.mac.value), string.lower(params.value.device.value.mac.value))<br />
if deletefiles then<br />
--APP.logevent("deleting "..path..d)<br />
os.remove(path..d)<br />
else<br />
--APP.logevent("moving "..path..d.." to "..path..newfile)<br />
os.rename(path..d, path..newfile)<br />
end<br />
end<br />
end<br />
end<br />
end<br />
end<br />
<br />
-- Then, notify the phone to pull it's config<br />
-- Try to get a valid extension currently on the device<br />
local oldexten = ""<br />
for name,val in pairs(oldparams.value) do<br />
if string.match(name, "^reg") and val.value.extension and val.value.extension.value ~= "" then<br />
oldexten = val.value.extension.value<br />
break<br />
end<br />
end<br />
if params.value.device and params.value.device.value.mac and params.value.device.value.mac.value ~= "" then<br />
devices[params.value.device.value.mac.value] = oldexten<br />
end<br />
if oldparams.value.device and oldparams.value.device.value.mac and oldparams.value.device.value.mac.value ~= "" then<br />
devices[oldparams.value.device.value.mac.value] = oldexten<br />
end<br />
<br />
for name,value in pairs(devices) do<br />
notify_device(name,value)<br />
end<br />
</pre><br />
* Create /etc/provisioning/provisioning_db_script<br />
<pre><br />
#!/usr/bin/lua<br />
<br />
local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin "<br />
local creation_script = {<br />
-- Parameters<br />
"INSERT INTO provisioning_params VALUES(default, 'freepstn', 'boolean', 'Free PSTN Access', '', 'false', '200', '')",<br />
<br />
-- Parameter Groups<br />
"INSERT INTO provisioning_groups VALUES(default, 'routing', 'Free PSTN Access', '31')",<br />
"INSERT INTO provisioning_groups VALUES(default, 'routing', 'No Free PSTN Access', '32')",<br />
<br />
-- param_groups_to_params (group_id, param_id, value, editable)<br />
"INSERT INTO param_groups_to_params VALUES((SELECT group_id FROM provisioning_groups WHERE label='Free PSTN Access'), (SELECT param_id FROM provisioning_params WHERE name='freepstn'), 'true', false)",<br />
"INSERT INTO param_groups_to_params VALUES((SELECT group_id FROM provisioning_groups WHERE label='No Free PSTN Access'), (SELECT param_id FROM provisioning_params WHERE name='freepstn'), 'false', false)",<br />
<br />
-- Classes<br />
-- provisioning_class_groups (class_group_id, name, label, seq)<br />
"INSERT INTO provisioning_class_groups VALUES(default, 'routing', 'Routing', '3')",<br />
<br />
-- provisioning_classes (class_id, class_group_id, label, seq)<br />
"INSERT INTO provisioning_classes VALUES(default, (SELECT class_group_id FROM provisioning_class_groups WHERE name='routing'), 'Free PSTN Access', '1')",<br />
"INSERT INTO provisioning_classes VALUES(default, (SELECT class_group_id FROM provisioning_class_groups WHERE name='routing'), 'No Free PSTN Access', '2')",<br />
<br />
-- classes_to_param_groups (class_id, group_id)<br />
"INSERT INTO classes_to_param_groups VALUES((SELECT class_id FROM provisioning_classes WHERE label='Free PSTN Access'), (SELECT group_id FROM provisioning_groups WHERE label='Free PSTN Access'))",<br />
"INSERT INTO classes_to_param_groups VALUES((SELECT class_id FROM provisioning_classes WHERE label='No Free PSTN Access'), (SELECT group_id FROM provisioning_groups WHERE label='No Free PSTN Access'))",<br />
<br />
-- provisioning_options<br />
"INSERT INTO provisioning_options VALUES((SELECT param_id FROM provisioning_params WHERE name='polycomringtone'), 'Warble', '15', '15')",<br />
"INSERT INTO provisioning_options VALUES((SELECT param_id FROM provisioning_params WHERE name='polycomringtone'), 'Analog Ring', '16', '16')",<br />
}<br />
<br />
<br />
local f = io.popen("/usr/share/acf/www/cgi-bin/cli /provisioning/provisioning/getdevicevalues")<br />
print(f:read("*a"))<br />
f:close()<br />
for i,c in ipairs(creation_script) do<br />
print(path..'psql -U postgres -c "'..c..'" provisioning 2>&1')<br />
local f = io.popen(path..'psql -U postgres -c "'..c..'" provisioning 2>&1')<br />
print(f:read("*a"))<br />
f:close()<br />
end<br />
</pre><br />
* chmod 755 /etc/provisioning/provisioning_db_script<br />
* /etc/provisioning/provisioning_db_script<br />
* echo '* * * * * run-parts /etc/periodic/1min' >> /etc/crontabs/root<br />
* mkdir /etc/periodic/1min/<br />
* /etc/periodic/1min/notify_device<br />
<pre><br />
#!/usr/bin/lua<br />
<br />
-- Load libraries<br />
require("luasql.postgres")<br />
<br />
-- Set variables<br />
local DatabaseName = "provisioning"<br />
local DatabaseUser = "postgres"<br />
local DatabasePassword<br />
<br />
local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin "<br />
local env<br />
local con<br />
<br />
-- ################################################################################<br />
-- LOCAL FUNCTIONS<br />
local function assert (v, m)<br />
if not v then<br />
m = m or "Assertion failed!"<br />
error(m, 0)<br />
end<br />
return v, m<br />
end<br />
<br />
-- Escape special characters in sql statements<br />
local escape = function(sql)<br />
sql = sql or ""<br />
sql = string.gsub(sql, "'", "''")<br />
return string.gsub(sql, "\\", "\\\\")<br />
end<br />
<br />
local databaseconnect = function()<br />
if not con then<br />
-- create environment object<br />
env = assert (luasql.postgres())<br />
-- connect to data source<br />
local err<br />
con, err = assert(env:connect(DatabaseName, DatabaseUser, DatabasePassword))<br />
return true<br />
end<br />
return false<br />
end<br />
<br />
local databasedisconnect = function()<br />
if env then<br />
env:close()<br />
env = nil<br />
end<br />
if con then<br />
con:close()<br />
con = nil<br />
end<br />
end<br />
<br />
local getselectresponse = function(sql)<br />
local retval = {}<br />
local cur = assert (con:execute(sql))<br />
local row = cur:fetch ({}, "a")<br />
while row do<br />
local tmp = {}<br />
for name,val in pairs(row) do<br />
tmp[name] = val<br />
end<br />
retval[#retval + 1] = tmp<br />
row = cur:fetch (row, "a")<br />
end<br />
cur:close()<br />
return retval<br />
end<br />
<br />
databaseconnect()<br />
<br />
-- First, let's notify for the seasoned requests<br />
local reqs = getselectresponse("SELECT * FROM notify WHERE seasoned='true'")<br />
for i,r in ipairs(reqs) do<br />
os.execute("/etc/provisioning/notify_device "..r.ipaddr.." "..r.extension)<br />
end<br />
<br />
-- Then mark any others as seasoned<br />
assert(con:execute("DELETE FROM notify WHERE seasoned='true'"))<br />
assert(con:execute("UPDATE notify SET seasoned='true' WHERE seasoned='false'"))<br />
<br />
databasedisconnect()<br />
</pre><br />
* apk add lighttpd<br />
* rm /etc/lighttpd/lighttpd.conf<br />
* ln -s /etc/provisioning/lighttpd.sample.conf /etc/lighttpd/lighttpd.conf<br />
* /etc/lighttpd/mod_cgi.conf:<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "",<br />
"" => ""<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
* /etc/init.d/lighttpd start<br />
* rc-update add lighttpd<br />
<br />
* Customize provisioning:<br />
<pre><br />
Parameter Default Value<br />
registrar IP address or host name of SIP Router(s)<br />
digitmap Digit map for your phone system (See Polycom Digit Map Reference)<br />
digitmaptimeout Timeout in seconds corresponding to digitmap<br />
sntpserver 10.2.0.1 (DMVPN spoke node)<br />
timezone Timezone information for this location - see below<br />
musiconhold SIP uri of the music-on-hold service - moh@media.office.example.net<br />
adminpassword Administration password for advanced settings on phone (on-screen and web interface)<br />
</pre><br />
* apk fetch --stdout acf-provisioning-polycom | tar -C / -zx<br />
* Create a test Polycom device and boot it in the voice network to verify that it works<br />
<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the SIP Media container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sipmedia -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sipmedia}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sipmedia/config, to reflect the network for the SIP Media container<br />
<br />
{{cat|/var/lib/lxc/sipmedia/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.sipmedia}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sipmedia}}<br />
<br />
== Enter the SIP Media container ==<br />
{{Cmd|lxc-console -n sipmedia}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.5<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
...<br />
<extension name="hold_music"> <br />
<condition field="destination_number" expression="^moh$"> <br />
<action application="answer"/> <br />
<action application="playback" data="$${hold_music}"/> <br />
</condition> <br />
</extension><br />
...<br />
<X-PRE-PROCESS cmd="set" data="hold_music=local_stream://default"/><br />
...<br />
FUTURE: ADD VOICEMAIL<br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
<br />
= Install the WiFi Web Proxy Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 172.17.48.1<br />
netmask 255.255.255.0<br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address 10.1.0.254<br />
netmask 255.255.255.252<br />
gateway 10.1.0.253<br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.1.0.131<br />
netmask 255.255.255.192<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10103
Small Office Services
2014-07-20T20:41:44Z
<p>Jbilyk: /* Install acf-provisioning */</p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
The assumption is made that the following VLANs and subnets are used as the DMVPN document did:<br />
<br />
{|class="wikitable"<br />
!'''Interface'''<br />
!'''Description'''<br />
!'''Subnet'''<br />
|-<br />
|bond0.3<br />
|Management<br />
|10.1.0.129/26<br />
|-<br />
|bond0.101<br />
|LAN<br />
|10.1.0.0/25<br />
|-<br />
|bond0.256<br />
|Internet from ISP1<br />
|Allocated from ISP<br />
|-<br />
|bond0.257<br />
|Internet from ISP2<br />
|Allocated from ISP<br />
|-<br />
|bond0.620<br />
|Transit between wifi proxy and dmvpn spoke node<br />
|10.1.0.252/30<br />
|-<br />
|bond0.701<br />
|WiFi clients (no access to DMVPN network)<br />
|172.17.48.0/24<br />
|-<br />
|bond0.1101<br />
|Voice<br />
|10.2.0.0/24<br />
|}<br />
<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.2<br />
netmask 255.255.255.192<br />
gateway 10.1.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$10.1.0.2",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth0<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth1<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth2<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Management VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.130<br />
netmask 255.255.255.192<br />
<br />
#WiFi VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address 172.16.48.2<br />
netmask 255.255.255.0<br />
<br />
#Voice VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.2.0.2<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
up ip address add 10.2.0.3/24 dev eth0<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers 10.2.0.1;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet 10.2.0.0 netmask 255.255.255.0<br />
{<br />
range "10.2.0.20 10.2.0.250";<br />
option domain-name-servers 10.2.0.2;<br />
option routers 10.2.0.1;<br />
option boot-server "http://10.2.0.4";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet 172.17.48.0 netmask 255.255.255.0<br />
{<br />
range "172.17.48.10 172.17.48.250";<br />
option routers 172.17.48.1;<br />
option domain-name-servers 172.17.48.1; <br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: 10.2.0.2<br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: 10.2.0.3<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.2.0.2 > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: 10.2.0.3<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A 10.2.0.3<br />
<br />
;A Records for SIP Devices<br />
sip IN A 10.2.0.4<br />
media IN A 10.2.0.5<br />
<br />
;NAPTR Records<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.media.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp.sip IN SRV 10 1 5060 sip<br />
_sip._udp.media IN SRV 10 1 5060 media<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.4<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'log_destination' variable to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
<br />
== Install acf-provisioning ==<br />
* vi /etc/kamailio/kamctlrc<br />
<pre><br />
SIP_DOMAIN=sip.office.example.net<br />
DBENGINE=PGSQL<br />
DBHOST=127.0.0.1<br />
DBNAME=openser<br />
DBRWUSER=openser<br />
DBRWPW="openser"<br />
DBROUSER=openserro<br />
DBROPW=openserro<br />
DBROOTUSER="postgres"<br />
</pre><br />
* yes | kamdbctl create openser<br />
* apk add acf-provisioning lua-socket lua-expat<br />
* Create /etc/provisioning/update_device_params.lua:<br />
<pre><br />
-- This is the script run after editing device params - basically only worried about extension and password<br />
local functions, params, oldparams = ...<br />
<br />
require("posix")<br />
require("luasql.postgres")<br />
<br />
local root = "/var/www/provisioning/htdocs/"<br />
local b62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"<br />
<br />
APP.logevent("got to update_device_params script")<br />
<br />
local function generatepw()<br />
-- generate a random 12-character alphanumeric string<br />
local file = io.open("/dev/urandom")<br />
local str = ""<br />
if file == nil then return nil end<br />
local size = 12<br />
while (size > 0 ) do<br />
local offset = (string.byte(file:read(1)) % 62) + 1<br />
str = str .. string.sub (b62, offset, offset)<br />
size = size - 1<br />
end<br />
return str<br />
end<br />
<br />
local function findip(mac)<br />
if not mac or mac == "" then<br />
return nil<br />
end<br />
local ipaddr = functions.getselectresponse("SELECT ip FROM provisioning_requests WHERE mac~*'"..mac.."'")<br />
if ipaddr and ipaddr[1] then<br />
return ipaddr[1].ip<br />
end<br />
end<br />
<br />
local function addfuturenotify(ipaddr, extension)<br />
local res, err = pcall(function()<br />
functions.runsqlcommand("DELETE FROM notify WHERE ipaddr='"..ipaddr.."' AND extension='"..extension.."'")<br />
end)<br />
if not res and err then<br />
if string.match(err, "relation \"(%S+)\" does not exist") then<br />
functions.runsqlcommand("CREATE TABLE notify (ipaddr text, extension text, seasoned boolean DEFAULT false)")<br />
else<br />
assert(res, err)<br />
end<br />
end<br />
-- if table missing, create it and delete again<br />
functions.runsqlcommand("INSERT INTO notify VALUES('"..ipaddr.."', '"..extension.."')")<br />
end<br />
<br />
local notify_device = function(mac, extension)<br />
local ipaddr = findip(mac)<br />
if ipaddr then<br />
APP.logevent("Notifying "..ipaddr.." to update for "..(mac or ""))<br />
os.execute("/etc/provisioning/notify_device "..ipaddr.." "..extension)<br />
addfuturenotify(ipaddr, extension)<br />
else<br />
APP.logevent("Warning - could not find IP address for "..(mac or ""))<br />
end<br />
end<br />
<br />
local kam = APP:new("kamailio/kamailio")<br />
<br />
-- A table of devices to notify to update<br />
local devices = {}<br />
<br />
-- First, we check the registration numbers / passwords to 1) set a random password (if necessary) 2) make sure password matches any other registrations to same extension 3) push changes (add / delete / or update) to Kam database<br />
-- Because this script also handles when device classes change, we have to consider that extensions are added / removed<br />
local regs = {}<br />
local forwarding = {"forwardnoanswerenable", "forwardnoanswer", "forwardbusyenable", "forwardbusy", "forwardallenable", "forwardall"}<br />
local forwardsettings = {} -- Collect forwarding settings<br />
local passwords = {} -- Collect old extension/password pairs<br />
for name,val in pairs(params.value) do<br />
if not regs[name] and string.match(name, "^reg") then<br />
regs[name] = true<br />
end<br />
end<br />
oldparams = oldparams or {value={}}<br />
for name,val in pairs(oldparams.value) do<br />
if string.match(name, "^reg") then<br />
if val.value and val.value.extension and val.value.password then<br />
passwords[val.value.extension.value] = val.value.password.value<br />
end<br />
if val.value and val.value.extension then<br />
local fwd = {}<br />
for i,f in ipairs(forwarding) do<br />
if val.value[f] then<br />
fwd[f] = val.value[f].value<br />
end<br />
end<br />
forwardsettings[val.value.extension.value] = fwd<br />
end<br />
if not regs[name] then<br />
regs[name] = true<br />
end<br />
end<br />
<br />
end<br />
local extension_id = params.value.reg1.value.extension.param_id<br />
local password_id = params.value.reg1.value.password.param_id<br />
functions.runsqlcommand("BEGIN TRANSACTION")<br />
for name,val in pairs(regs) do<br />
local new = ""<br />
local old = ""<br />
if params.value[name] then new = params.value[name].value.extension.value end<br />
if oldparams.value[name] then old = oldparams.value[name].value.extension.value end<br />
if new ~= old then<br />
-- Extension changed<br />
-- First, let's remove the stuff for the old extension<br />
if old ~= "" then<br />
local others = functions.getselectresponse("SELECT count(*) FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..old.."'")<br />
if others[1].count == "0" then<br />
APP.logevent("Removing old registration "..old)<br />
-- remove the registration<br />
kam.model.delete_user(old)<br />
end<br />
end<br />
-- Now, add the new extension<br />
if new ~= "" then<br />
local pass<br />
if params.value[name].value.password.value ~= "" and (not oldparams.value[name] or (oldparams.value[name].value.password.value ~= params.value[name].value.password.value)) then<br />
-- The password parameter was changed and not blank, so use it<br />
pass = params.value[name].value.password.value<br />
APP.logevent("Added a new registration "..new.." with specified password "..pass)<br />
-- There may be other devices with this extension<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
-- We'll notify whether it changed or not<br />
devices[o.value] = new<br />
end<br />
elseif passwords[new] then<br />
pass = passwords[new]<br />
APP.logevent("Added a new registration "..new.." with reused password "..pass)<br />
else<br />
local others = functions.getselectresponse("SELECT * FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."' AND device_id!='"..params.value.device_id.value.."'")<br />
-- If this is a new registration, use a new password<br />
if #others == 0 then<br />
pass = generatepw()<br />
APP.logevent("Added a new registration "..new.." with random password "..pass)<br />
else<br />
-- Use the old password<br />
local p = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id='"..password_id.."' AND device_id='"..others[1].device_id.."' AND group_name='"..others[1].group_name.."' LIMIT 1")<br />
pass = p[1].value<br />
APP.logevent("Added a new registration "..new.." with reused password "..pass)<br />
end<br />
end<br />
passwords[new] = pass<br />
params.value[name].value.password.value = pass<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..password_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..password_id.."', '"..pass.."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
local u = kam.model.get_user(new)<br />
if u.value.username.errtxt then<br />
-- Add this registration to Kam<br />
local u = kam.model.get_new_user()<br />
u.value.username.value = new<br />
u.value.password.value = pass<br />
u.value.password_confirm.value = pass<br />
kam.model.create_new_user(u)<br />
else<br />
u.value.password.value = pass<br />
u.value.password_confirm.value = pass<br />
kam.model.update_user(u)<br />
end<br />
-- Let's also look at the forwarding settings<br />
local change = false<br />
local supported = false<br />
local fwd = {}<br />
for i,f in ipairs(forwarding) do<br />
if params.value[name].value[f] then<br />
supported = true<br />
fwd[f] = params.value[name].value[f].value<br />
if ((not oldparams.value[name] or not oldparams.value[name].value[f]) and (params.value[name].value[f].value ~= params.value[name].value[f].default)) or<br />
(oldparams.value[name] and oldparams.value[name].value[f] and (params.value[name].value[f].value ~= oldparams.value[name].value[f].value)) then<br />
change = true<br />
end<br />
end<br />
if change then<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
-- We'll notify whether it changed or not<br />
devices[o.value] = new<br />
end<br />
end<br />
end<br />
if supported then<br />
if not change and forwardsettings[new] then<br />
fwd = forwardsettings[new]<br />
elseif not change then<br />
-- This is a new extension, and the forwarding has not been set. We should check to see if there are any other devices with this extension<br />
local others = functions.getselectresponse("SELECT * FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."' AND device_id!='"..params.value.device_id.value.."'")<br />
if #others > 0 then<br />
-- Use the existing settings<br />
for i,f in ipairs(forwarding) do<br />
local v = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id='"..params.value[name].value[f].param_id.."' AND device_id='"..others[1].device_id.."' AND group_name='"..others[1].group_name.."' LIMIT 1")<br />
if #v > 0 then<br />
fwd[f] = v[1].value<br />
else<br />
fwd[f] = params.value[name].value[f].default<br />
end<br />
end<br />
end<br />
end<br />
if not change then<br />
for i,f in ipairs(forwarding) do<br />
params.value[name].value[f].value = fwd[f]<br />
end<br />
end<br />
forwardsettings[new] = fwd<br />
for i,f in ipairs(forwarding) do<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..params.value[name].value[f].param_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
if fwd[f] ~= params.value[name].value[f].default then<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..params.value[name].value[f].param_id.."', '"..tostring(fwd[f]).."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
end<br />
end<br />
end<br />
end<br />
elseif params.value[name] and oldparams.value[name] and params.value[name].value.extension.value ~= "" then<br />
if params.value[name].value.password.value ~= oldparams.value[name].value.password.value then<br />
-- Password changed - make any other registrations to this extension also change<br />
local pass = params.value[name].value.password.value<br />
if pass and pass ~= "" then<br />
APP.logevent("Password changed for "..new.." from "..oldparams.value[name].value.password.value.." to "..pass)<br />
else<br />
pass = generatepw()<br />
APP.logevent("Password cleared for "..new..", so set new random password "..pass)<br />
end<br />
passwords[new] = pass<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..password_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..password_id.."', '"..pass.."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
local u = kam.model.get_user(new)<br />
u.value.password.value = params.value[name].value.password.value<br />
u.value.password_confirm.value = params.value[name].value.password.value<br />
kam.model.update_user(u)<br />
-- Have to notify those other devices too<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
devices[o.value] = new<br />
end<br />
end<br />
local change = false<br />
local fwd = {}<br />
for i,f in ipairs(forwarding) do<br />
if params.value[name].value[f] and (not oldparams.value[name].value[f] or params.value[name].value[f].value ~= oldparams.value[name].value[f].value) then<br />
change = true<br />
break<br />
end<br />
end<br />
if change then<br />
-- Forwarding settings changed - make any other registrations to this extension also change<br />
for i,f in ipairs(forwarding) do<br />
functions.runsqlcommand("DELETE FROM provisioning_values WHERE param_id='"..params.value[name].value[f].param_id.."' AND (device_id, group_name) IN (SELECT device_id, group_name FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
if params.value[name].value[f].value ~= params.value[name].value[f].default then<br />
functions.runsqlcommand("INSERT INTO provisioning_values (SELECT device_id, group_name, '"..params.value[name].value[f].param_id.."', '"..tostring(params.value[name].value[f].value).."' FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
end<br />
end<br />
-- Have to notify those other devices too<br />
local others = functions.getselectresponse("SELECT value FROM provisioning_values WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name='mac') AND device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND value='"..new.."')")<br />
for i,o in ipairs(others) do<br />
devices[o.value] = new<br />
end<br />
end<br />
end<br />
end<br />
functions.runsqlcommand("COMMIT")<br />
<br />
-- If reg1 or freepstn changed, then need to change free-pstn in kam<br />
-- Since there can be multiple devices with the same reg1, we can't rely on params and oldparams<br />
-- Check both reg's<br />
--APP.logevent(session.serialize("params", params))<br />
local reg = {}<br />
if oldparams.value.reg1 and oldparams.value.reg1.value.extension and oldparams.value.reg1.value.extension.value ~= "" then<br />
reg[oldparams.value.reg1.value.extension.value] = false<br />
end<br />
if params.value.reg1 and params.value.reg1.value.extension and params.value.reg1.value.extension.value ~= "" then<br />
local pstn = false<br />
if params.value.routing and params.value.routing.value.freepstn then<br />
pstn = params.value.routing.value.freepstn.value<br />
end<br />
reg[params.value.reg1.value.extension.value] = pstn<br />
end<br />
<br />
APP.logevent("Looking at free-pstn")<br />
for r,f in pairs(reg) do<br />
-- if we're not sure, check provisioning database<br />
if not f then<br />
-- Most devices will have free-pstn due to class-of-service, but can be overridden, so this can get tricky<br />
-- Check all devices where reg1 extension = r, and see what the freepstn value is for each<br />
local others = functions.getselectresponse("SELECT CASE WHEN v.value IS NOT NULL THEN v.value WHEN g2p.value IS NOT NULL THEN g2p.value ELSE p.value END AS value "..<br />
"FROM (devices_to_classes d2t JOIN provisioning_classes t USING(class_id) JOIN classes_to_param_groups t2g USING (class_id) JOIN provisioning_groups g USING(group_id) "..<br />
"JOIN param_groups_to_params g2p USING(group_id) JOIN provisioning_params p USING(param_id)) LEFT JOIN provisioning_values v ON (d2t.device_id=v.device_id AND p.param_id=v.param_id AND g.name=v.group_name ) "..<br />
"WHERE p.name='freepstn' AND d2t.device_id IN (SELECT device_id FROM provisioning_values WHERE param_id='"..extension_id.."' AND group_name='reg1' AND value='"..r.."')")<br />
for i,o in ipairs(others) do<br />
-- Now check the freepstn value for each one<br />
if o.value == "true" then<br />
f = true<br />
break<br />
end<br />
end<br />
end<br />
-- Now, check the Kamailio group table<br />
local alreadythere = false<br />
local entries = kam.model.list_table_entries("grp")<br />
for i,e in ipairs(entries.value.entries.value) do<br />
if e.username == r then<br />
alreadythere = true<br />
if not f then<br />
APP.logevent("Removing free-pstn for "..r)<br />
-- Remove free-pstn from the old extension<br />
kam.model.delete_table_entry("grp", e.id)<br />
end<br />
break<br />
end<br />
end<br />
if f and not alreadythere then<br />
APP.logevent("Adding free-pstn for "..r)<br />
-- Add free-pstn to the new extension<br />
local e = kam.model.get_table_entry("grp")<br />
e.value.username.value = r<br />
e.value.domain.value = ""<br />
e.value.grp.value = "free-pstn"<br />
e.value.last_modified.value = os.date("%c")<br />
kam.model.create_table_entry(e)<br />
end<br />
end<br />
<br />
kam:destroy()<br />
<br />
-- If the mac address changed for Polycom with valid MAC (not blank or all 0's), we need to move the associated config files<br />
if oldparams.value.device and oldparams.value.device.value.mac and oldparams.value.device.value.mac.value ~= "" and params.value.device and params.value.device.value.mac and params.value.device.value.mac.value ~= oldparams.value.device.value.mac.value then<br />
if string.match(oldparams.value.device.label, "Polycom") and string.match(oldparams.value.device.value.mac.value, "[1-9A-F]") then<br />
local deletefiles = true<br />
if string.match(params.value.device.value.mac.value, "[1-9A-F]") then<br />
--APP.logevent("Moving files for "..oldparams.value.device.value.mac.value)<br />
deletefiles = false<br />
else<br />
--APP.logevent("Deleting files for "..oldparams.value.device.value.mac.value)<br />
end<br />
local path = root.."Polycom/"<br />
if posix.stat(path, "type") == "directory" then<br />
for d in posix.files(path) do<br />
if string.match(d, string.lower(oldparams.value.device.value.mac.value)) and posix.stat(path..d, "type") == "regular" then<br />
local newfile = string.gsub(d, string.lower(oldparams.value.device.value.mac.value), string.lower(params.value.device.value.mac.value))<br />
if deletefiles then<br />
--APP.logevent("deleting "..path..d)<br />
os.remove(path..d)<br />
else<br />
--APP.logevent("moving "..path..d.." to "..path..newfile)<br />
os.rename(path..d, path..newfile)<br />
end<br />
end<br />
end<br />
end<br />
end<br />
end<br />
<br />
-- Then, notify the phone to pull it's config<br />
-- Try to get a valid extension currently on the device<br />
local oldexten = ""<br />
for name,val in pairs(oldparams.value) do<br />
if string.match(name, "^reg") and val.value.extension and val.value.extension.value ~= "" then<br />
oldexten = val.value.extension.value<br />
break<br />
end<br />
end<br />
if params.value.device and params.value.device.value.mac and params.value.device.value.mac.value ~= "" then<br />
devices[params.value.device.value.mac.value] = oldexten<br />
end<br />
if oldparams.value.device and oldparams.value.device.value.mac and oldparams.value.device.value.mac.value ~= "" then<br />
devices[oldparams.value.device.value.mac.value] = oldexten<br />
end<br />
<br />
for name,value in pairs(devices) do<br />
notify_device(name,value)<br />
end<br />
</pre><br />
* Create /etc/provisioning/provisioning_db_script<br />
<pre><br />
#!/usr/bin/lua<br />
<br />
local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin "<br />
local creation_script = {<br />
-- Parameters<br />
"INSERT INTO provisioning_params VALUES(default, 'freepstn', 'boolean', 'Free PSTN Access', '', 'false', '200', '')",<br />
<br />
-- Parameter Groups<br />
"INSERT INTO provisioning_groups VALUES(default, 'routing', 'Free PSTN Access', '31')",<br />
"INSERT INTO provisioning_groups VALUES(default, 'routing', 'No Free PSTN Access', '32')",<br />
<br />
-- param_groups_to_params (group_id, param_id, value, editable)<br />
"INSERT INTO param_groups_to_params VALUES((SELECT group_id FROM provisioning_groups WHERE label='Free PSTN Access'), (SELECT param_id FROM provisioning_params WHERE name='freepstn'), 'true', false)",<br />
"INSERT INTO param_groups_to_params VALUES((SELECT group_id FROM provisioning_groups WHERE label='No Free PSTN Access'), (SELECT param_id FROM provisioning_params WHERE name='freepstn'), 'false', false)",<br />
<br />
-- Classes<br />
-- provisioning_class_groups (class_group_id, name, label, seq)<br />
"INSERT INTO provisioning_class_groups VALUES(default, 'routing', 'Routing', '3')",<br />
<br />
-- provisioning_classes (class_id, class_group_id, label, seq)<br />
"INSERT INTO provisioning_classes VALUES(default, (SELECT class_group_id FROM provisioning_class_groups WHERE name='routing'), 'Free PSTN Access', '1')",<br />
"INSERT INTO provisioning_classes VALUES(default, (SELECT class_group_id FROM provisioning_class_groups WHERE name='routing'), 'No Free PSTN Access', '2')",<br />
<br />
-- classes_to_param_groups (class_id, group_id)<br />
"INSERT INTO classes_to_param_groups VALUES((SELECT class_id FROM provisioning_classes WHERE label='Free PSTN Access'), (SELECT group_id FROM provisioning_groups WHERE label='Free PSTN Access'))",<br />
"INSERT INTO classes_to_param_groups VALUES((SELECT class_id FROM provisioning_classes WHERE label='No Free PSTN Access'), (SELECT group_id FROM provisioning_groups WHERE label='No Free PSTN Access'))",<br />
<br />
-- provisioning_options<br />
"INSERT INTO provisioning_options VALUES((SELECT param_id FROM provisioning_params WHERE name='polycomringtone'), 'Warble', '15', '15')",<br />
"INSERT INTO provisioning_options VALUES((SELECT param_id FROM provisioning_params WHERE name='polycomringtone'), 'Analog Ring', '16', '16')",<br />
}<br />
<br />
<br />
local f = io.popen("/usr/share/acf/www/cgi-bin/cli /provisioning/provisioning/getdevicevalues")<br />
print(f:read("*a"))<br />
f:close()<br />
for i,c in ipairs(creation_script) do<br />
print(path..'psql -U postgres -c "'..c..'" provisioning 2>&1')<br />
local f = io.popen(path..'psql -U postgres -c "'..c..'" provisioning 2>&1')<br />
print(f:read("*a"))<br />
f:close()<br />
end<br />
</pre><br />
* chmod 755 /etc/provisioning/provisioning_db_script<br />
* /etc/provisioning/provisioning_db_script<br />
* echo '* * * * * run-parts /etc/periodic/1min' >> /etc/crontabs/root<br />
* mkdir /etc/periodic/1min/<br />
* /etc/periodic/1min/notify_device<br />
<pre><br />
#!/usr/bin/lua<br />
<br />
-- Load libraries<br />
require("luasql.postgres")<br />
<br />
-- Set variables<br />
local DatabaseName = "provisioning"<br />
local DatabaseUser = "postgres"<br />
local DatabasePassword<br />
<br />
local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin "<br />
local env<br />
local con<br />
<br />
-- ################################################################################<br />
-- LOCAL FUNCTIONS<br />
local function assert (v, m)<br />
if not v then<br />
m = m or "Assertion failed!"<br />
error(m, 0)<br />
end<br />
return v, m<br />
end<br />
<br />
-- Escape special characters in sql statements<br />
local escape = function(sql)<br />
sql = sql or ""<br />
sql = string.gsub(sql, "'", "''")<br />
return string.gsub(sql, "\\", "\\\\")<br />
end<br />
<br />
local databaseconnect = function()<br />
if not con then<br />
-- create environment object<br />
env = assert (luasql.postgres())<br />
-- connect to data source<br />
local err<br />
con, err = assert(env:connect(DatabaseName, DatabaseUser, DatabasePassword))<br />
return true<br />
end<br />
return false<br />
end<br />
<br />
local databasedisconnect = function()<br />
if env then<br />
env:close()<br />
env = nil<br />
end<br />
if con then<br />
con:close()<br />
con = nil<br />
end<br />
end<br />
<br />
local getselectresponse = function(sql)<br />
local retval = {}<br />
local cur = assert (con:execute(sql))<br />
local row = cur:fetch ({}, "a")<br />
while row do<br />
local tmp = {}<br />
for name,val in pairs(row) do<br />
tmp[name] = val<br />
end<br />
retval[#retval + 1] = tmp<br />
row = cur:fetch (row, "a")<br />
end<br />
cur:close()<br />
return retval<br />
end<br />
<br />
databaseconnect()<br />
<br />
-- First, let's notify for the seasoned requests<br />
local reqs = getselectresponse("SELECT * FROM notify WHERE seasoned='true'")<br />
for i,r in ipairs(reqs) do<br />
os.execute("/etc/provisioning/notify_device "..r.ipaddr.." "..r.extension)<br />
end<br />
<br />
-- Then mark any others as seasoned<br />
assert(con:execute("DELETE FROM notify WHERE seasoned='true'"))<br />
assert(con:execute("UPDATE notify SET seasoned='true' WHERE seasoned='false'"))<br />
<br />
databasedisconnect()<br />
</pre><br />
* apk add lighttpd<br />
* rm /etc/lighttpd/lighttpd.conf<br />
* ln -s /etc/provisioning/lighttpd.sample.conf /etc/lighttpd/lighttpd.conf<br />
* /etc/lighttpd/mod_cgi.conf:<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "",<br />
"" => ""<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
* /etc/init.d/lighttpd start<br />
* rc-update add lighttpd<br />
<br />
* Customize provisioning:<br />
<pre><br />
Parameter Default Value<br />
registrar IP address or host name of SIP Router(s)<br />
digitmap Digit map for your phone system (See Polycom Digit Map Reference)<br />
digitmaptimeout Timeout in seconds corresponding to digitmap<br />
sntpserver 10.2.0.1 (DMVPN spoke node)<br />
timezone Timezone information for this location - see below<br />
musiconhold SIP uri of the music-on-hold service - moh@media.office.example.net<br />
adminpassword Administration password for advanced settings on phone (on-screen and web interface)<br />
</pre><br />
* apk fetch --stdout acf-provisioning-polycom | tar -C / -zx<br />
* Create a test Polycom device and boot it in the voice network to verify that it works<br />
<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the SIP Media container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sipmedia -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sipmedia}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sipmedia/config, to reflect the network for the SIP Media container<br />
<br />
{{cat|/var/lib/lxc/sipmedia/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.sipmedia}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sipmedia}}<br />
<br />
== Enter the SIP Media container ==<br />
{{Cmd|lxc-console -n sipmedia}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.5<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
TO POPULATE<br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
= Install the WiFi Web Proxy Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 172.17.48.1<br />
netmask 255.255.255.0<br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address 10.1.0.254<br />
netmask 255.255.255.252<br />
gateway 10.1.0.253<br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.1.0.131<br />
netmask 255.255.255.192<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10102
Small Office Services
2014-07-20T20:27:47Z
<p>Jbilyk: /* Enter the wifi container */</p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
The assumption is made that the following VLANs and subnets are used as the DMVPN document did:<br />
<br />
{|class="wikitable"<br />
!'''Interface'''<br />
!'''Description'''<br />
!'''Subnet'''<br />
|-<br />
|bond0.3<br />
|Management<br />
|10.1.0.129/26<br />
|-<br />
|bond0.101<br />
|LAN<br />
|10.1.0.0/25<br />
|-<br />
|bond0.256<br />
|Internet from ISP1<br />
|Allocated from ISP<br />
|-<br />
|bond0.257<br />
|Internet from ISP2<br />
|Allocated from ISP<br />
|-<br />
|bond0.620<br />
|Transit between wifi proxy and dmvpn spoke node<br />
|10.1.0.252/30<br />
|-<br />
|bond0.701<br />
|WiFi clients (no access to DMVPN network)<br />
|172.17.48.0/24<br />
|-<br />
|bond0.1101<br />
|Voice<br />
|10.2.0.0/24<br />
|}<br />
<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.2<br />
netmask 255.255.255.192<br />
gateway 10.1.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$10.1.0.2",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth0<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth1<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth2<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Management VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.130<br />
netmask 255.255.255.192<br />
<br />
#WiFi VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address 172.16.48.2<br />
netmask 255.255.255.0<br />
<br />
#Voice VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.2.0.2<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
up ip address add 10.2.0.3/24 dev eth0<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers 10.2.0.1;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet 10.2.0.0 netmask 255.255.255.0<br />
{<br />
range "10.2.0.20 10.2.0.250";<br />
option domain-name-servers 10.2.0.2;<br />
option routers 10.2.0.1;<br />
option boot-server "http://10.2.0.4";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet 172.17.48.0 netmask 255.255.255.0<br />
{<br />
range "172.17.48.10 172.17.48.250";<br />
option routers 172.17.48.1;<br />
option domain-name-servers 172.17.48.1; <br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: 10.2.0.2<br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: 10.2.0.3<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.2.0.2 > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: 10.2.0.3<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A 10.2.0.3<br />
<br />
;A Records for SIP Devices<br />
sip IN A 10.2.0.4<br />
media IN A 10.2.0.5<br />
<br />
;NAPTR Records<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.media.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp.sip IN SRV 10 1 5060 sip<br />
_sip._udp.media IN SRV 10 1 5060 media<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.4<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'log_destination' variable to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
<br />
== Install acf-provisioning ==<br />
TO POPULATE<br />
<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the SIP Media container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sipmedia -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sipmedia}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sipmedia/config, to reflect the network for the SIP Media container<br />
<br />
{{cat|/var/lib/lxc/sipmedia/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.sipmedia}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sipmedia}}<br />
<br />
== Enter the SIP Media container ==<br />
{{Cmd|lxc-console -n sipmedia}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.5<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
TO POPULATE<br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
= Install the WiFi Web Proxy Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 172.17.48.1<br />
netmask 255.255.255.0<br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address 10.1.0.254<br />
netmask 255.255.255.252<br />
gateway 10.1.0.253<br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.1.0.131<br />
netmask 255.255.255.192<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10101
Small Office Services
2014-07-20T20:26:42Z
<p>Jbilyk: /* Enter the SIP Media container */</p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
The assumption is made that the following VLANs and subnets are used as the DMVPN document did:<br />
<br />
{|class="wikitable"<br />
!'''Interface'''<br />
!'''Description'''<br />
!'''Subnet'''<br />
|-<br />
|bond0.3<br />
|Management<br />
|10.1.0.129/26<br />
|-<br />
|bond0.101<br />
|LAN<br />
|10.1.0.0/25<br />
|-<br />
|bond0.256<br />
|Internet from ISP1<br />
|Allocated from ISP<br />
|-<br />
|bond0.257<br />
|Internet from ISP2<br />
|Allocated from ISP<br />
|-<br />
|bond0.620<br />
|Transit between wifi proxy and dmvpn spoke node<br />
|10.1.0.252/30<br />
|-<br />
|bond0.701<br />
|WiFi clients (no access to DMVPN network)<br />
|172.17.48.0/24<br />
|-<br />
|bond0.1101<br />
|Voice<br />
|10.2.0.0/24<br />
|}<br />
<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.2<br />
netmask 255.255.255.192<br />
gateway 10.1.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$10.1.0.2",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth0<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth1<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth2<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Management VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.130<br />
netmask 255.255.255.192<br />
<br />
#WiFi VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address 172.16.48.2<br />
netmask 255.255.255.0<br />
<br />
#Voice VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.2.0.2<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
up ip address add 10.2.0.3/24 dev eth0<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers 10.2.0.1;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet 10.2.0.0 netmask 255.255.255.0<br />
{<br />
range "10.2.0.20 10.2.0.250";<br />
option domain-name-servers 10.2.0.2;<br />
option routers 10.2.0.1;<br />
option boot-server "http://10.2.0.4";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet 172.17.48.0 netmask 255.255.255.0<br />
{<br />
range "172.17.48.10 172.17.48.250";<br />
option routers 172.17.48.1;<br />
option domain-name-servers 172.17.48.1; <br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: 10.2.0.2<br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: 10.2.0.3<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.2.0.2 > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: 10.2.0.3<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A 10.2.0.3<br />
<br />
;A Records for SIP Devices<br />
sip IN A 10.2.0.4<br />
media IN A 10.2.0.5<br />
<br />
;NAPTR Records<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.media.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp.sip IN SRV 10 1 5060 sip<br />
_sip._udp.media IN SRV 10 1 5060 media<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.4<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'log_destination' variable to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
<br />
== Install acf-provisioning ==<br />
TO POPULATE<br />
<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the SIP Media container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sipmedia -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sipmedia}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sipmedia/config, to reflect the network for the SIP Media container<br />
<br />
{{cat|/var/lib/lxc/sipmedia/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.sipmedia}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sipmedia}}<br />
<br />
== Enter the SIP Media container ==<br />
{{Cmd|lxc-console -n sipmedia}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.5<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
TO POPULATE<br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
= Install the WiFi Web Proxy Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WIFI_IP_ADDRESS%><br />
netmask <%VPNc_WIFI_NETMASK%><br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address <%WIFI_TRANSIT_IP_ADDRESS%><br />
netmask <%WIFI_TRANSIT_NETMASK%><br />
gateway <%DMVPN_WIFI_TRANSIT_IP_ADDRESS%><br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address <%WIFI_MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10100
Small Office Services
2014-07-20T20:25:53Z
<p>Jbilyk: /* Install and Configure Postgresql */</p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
The assumption is made that the following VLANs and subnets are used as the DMVPN document did:<br />
<br />
{|class="wikitable"<br />
!'''Interface'''<br />
!'''Description'''<br />
!'''Subnet'''<br />
|-<br />
|bond0.3<br />
|Management<br />
|10.1.0.129/26<br />
|-<br />
|bond0.101<br />
|LAN<br />
|10.1.0.0/25<br />
|-<br />
|bond0.256<br />
|Internet from ISP1<br />
|Allocated from ISP<br />
|-<br />
|bond0.257<br />
|Internet from ISP2<br />
|Allocated from ISP<br />
|-<br />
|bond0.620<br />
|Transit between wifi proxy and dmvpn spoke node<br />
|10.1.0.252/30<br />
|-<br />
|bond0.701<br />
|WiFi clients (no access to DMVPN network)<br />
|172.17.48.0/24<br />
|-<br />
|bond0.1101<br />
|Voice<br />
|10.2.0.0/24<br />
|}<br />
<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.2<br />
netmask 255.255.255.192<br />
gateway 10.1.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$10.1.0.2",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth0<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth1<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth2<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Management VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.130<br />
netmask 255.255.255.192<br />
<br />
#WiFi VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address 172.16.48.2<br />
netmask 255.255.255.0<br />
<br />
#Voice VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.2.0.2<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
up ip address add 10.2.0.3/24 dev eth0<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers 10.2.0.1;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet 10.2.0.0 netmask 255.255.255.0<br />
{<br />
range "10.2.0.20 10.2.0.250";<br />
option domain-name-servers 10.2.0.2;<br />
option routers 10.2.0.1;<br />
option boot-server "http://10.2.0.4";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet 172.17.48.0 netmask 255.255.255.0<br />
{<br />
range "172.17.48.10 172.17.48.250";<br />
option routers 172.17.48.1;<br />
option domain-name-servers 172.17.48.1; <br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: 10.2.0.2<br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: 10.2.0.3<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.2.0.2 > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: 10.2.0.3<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A 10.2.0.3<br />
<br />
;A Records for SIP Devices<br />
sip IN A 10.2.0.4<br />
media IN A 10.2.0.5<br />
<br />
;NAPTR Records<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.media.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp.sip IN SRV 10 1 5060 sip<br />
_sip._udp.media IN SRV 10 1 5060 media<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.4<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'log_destination' variable to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
<br />
== Install acf-provisioning ==<br />
TO POPULATE<br />
<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the SIP Media container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sipmedia -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sipmedia}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sipmedia/config, to reflect the network for the SIP Media container<br />
<br />
{{cat|/var/lib/lxc/sipmedia/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.sipmedia}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sipmedia}}<br />
<br />
== Enter the SIP Media container ==<br />
{{Cmd|lxc-console -n sipmedia}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%B2BUA_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
TO POPULATE<br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
= Install the WiFi Web Proxy Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WIFI_IP_ADDRESS%><br />
netmask <%VPNc_WIFI_NETMASK%><br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address <%WIFI_TRANSIT_IP_ADDRESS%><br />
netmask <%WIFI_TRANSIT_NETMASK%><br />
gateway <%DMVPN_WIFI_TRANSIT_IP_ADDRESS%><br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address <%WIFI_MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10099
Small Office Services
2014-07-20T20:25:24Z
<p>Jbilyk: /* Enter the sip container */</p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
The assumption is made that the following VLANs and subnets are used as the DMVPN document did:<br />
<br />
{|class="wikitable"<br />
!'''Interface'''<br />
!'''Description'''<br />
!'''Subnet'''<br />
|-<br />
|bond0.3<br />
|Management<br />
|10.1.0.129/26<br />
|-<br />
|bond0.101<br />
|LAN<br />
|10.1.0.0/25<br />
|-<br />
|bond0.256<br />
|Internet from ISP1<br />
|Allocated from ISP<br />
|-<br />
|bond0.257<br />
|Internet from ISP2<br />
|Allocated from ISP<br />
|-<br />
|bond0.620<br />
|Transit between wifi proxy and dmvpn spoke node<br />
|10.1.0.252/30<br />
|-<br />
|bond0.701<br />
|WiFi clients (no access to DMVPN network)<br />
|172.17.48.0/24<br />
|-<br />
|bond0.1101<br />
|Voice<br />
|10.2.0.0/24<br />
|}<br />
<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.2<br />
netmask 255.255.255.192<br />
gateway 10.1.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$10.1.0.2",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth0<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth1<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth2<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Management VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.130<br />
netmask 255.255.255.192<br />
<br />
#WiFi VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address 172.16.48.2<br />
netmask 255.255.255.0<br />
<br />
#Voice VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.2.0.2<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
up ip address add 10.2.0.3/24 dev eth0<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers 10.2.0.1;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet 10.2.0.0 netmask 255.255.255.0<br />
{<br />
range "10.2.0.20 10.2.0.250";<br />
option domain-name-servers 10.2.0.2;<br />
option routers 10.2.0.1;<br />
option boot-server "http://10.2.0.4";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet 172.17.48.0 netmask 255.255.255.0<br />
{<br />
range "172.17.48.10 172.17.48.250";<br />
option routers 172.17.48.1;<br />
option domain-name-servers 172.17.48.1; <br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: 10.2.0.2<br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: 10.2.0.3<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.2.0.2 > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: 10.2.0.3<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A 10.2.0.3<br />
<br />
;A Records for SIP Devices<br />
sip IN A 10.2.0.4<br />
media IN A 10.2.0.5<br />
<br />
;NAPTR Records<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.media.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp.sip IN SRV 10 1 5060 sip<br />
_sip._udp.media IN SRV 10 1 5060 media<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.2.0.4<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'listen_addresses', and the 'log_destination' variables to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
listen_addresses {{=}}'<%SIP_IP_ADDRESS%><br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
<br />
== Install acf-provisioning ==<br />
TO POPULATE<br />
<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the SIP Media container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sipmedia -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sipmedia}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sipmedia/config, to reflect the network for the SIP Media container<br />
<br />
{{cat|/var/lib/lxc/sipmedia/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.sipmedia}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sipmedia}}<br />
<br />
== Enter the SIP Media container ==<br />
{{Cmd|lxc-console -n sipmedia}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%B2BUA_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
TO POPULATE<br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
= Install the WiFi Web Proxy Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WIFI_IP_ADDRESS%><br />
netmask <%VPNc_WIFI_NETMASK%><br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address <%WIFI_TRANSIT_IP_ADDRESS%><br />
netmask <%WIFI_TRANSIT_NETMASK%><br />
gateway <%DMVPN_WIFI_TRANSIT_IP_ADDRESS%><br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address <%WIFI_MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10098
Small Office Services
2014-07-20T20:24:39Z
<p>Jbilyk: /* Install the DHCP and DNS server Container */</p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
The assumption is made that the following VLANs and subnets are used as the DMVPN document did:<br />
<br />
{|class="wikitable"<br />
!'''Interface'''<br />
!'''Description'''<br />
!'''Subnet'''<br />
|-<br />
|bond0.3<br />
|Management<br />
|10.1.0.129/26<br />
|-<br />
|bond0.101<br />
|LAN<br />
|10.1.0.0/25<br />
|-<br />
|bond0.256<br />
|Internet from ISP1<br />
|Allocated from ISP<br />
|-<br />
|bond0.257<br />
|Internet from ISP2<br />
|Allocated from ISP<br />
|-<br />
|bond0.620<br />
|Transit between wifi proxy and dmvpn spoke node<br />
|10.1.0.252/30<br />
|-<br />
|bond0.701<br />
|WiFi clients (no access to DMVPN network)<br />
|172.17.48.0/24<br />
|-<br />
|bond0.1101<br />
|Voice<br />
|10.2.0.0/24<br />
|}<br />
<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.2<br />
netmask 255.255.255.192<br />
gateway 10.1.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$10.1.0.2",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth0<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth1<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth2<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Management VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.130<br />
netmask 255.255.255.192<br />
<br />
#WiFi VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address 172.16.48.2<br />
netmask 255.255.255.0<br />
<br />
#Voice VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address 10.2.0.2<br />
netmask 255.255.255.0<br />
gateway 10.2.0.1<br />
up ip address add 10.2.0.3/24 dev eth0<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://10.1.0.2:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers 10.2.0.1;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet 10.2.0.0 netmask 255.255.255.0<br />
{<br />
range "10.2.0.20 10.2.0.250";<br />
option domain-name-servers 10.2.0.2;<br />
option routers 10.2.0.1;<br />
option boot-server "http://10.2.0.4";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet 172.17.48.0 netmask 255.255.255.0<br />
{<br />
range "172.17.48.10 172.17.48.250";<br />
option routers 172.17.48.1;<br />
option domain-name-servers 172.17.48.1; <br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: 10.2.0.2<br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: 10.2.0.3<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.2.0.2 > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: 10.2.0.3<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A 10.2.0.3<br />
<br />
;A Records for SIP Devices<br />
sip IN A 10.2.0.4<br />
media IN A 10.2.0.5<br />
<br />
;NAPTR Records<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.media.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp.sip IN SRV 10 1 5060 sip<br />
_sip._udp.media IN SRV 10 1 5060 media<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%SIP_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'listen_addresses', and the 'log_destination' variables to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
listen_addresses {{=}}'<%SIP_IP_ADDRESS%><br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
<br />
== Install acf-provisioning ==<br />
TO POPULATE<br />
<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the SIP Media container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sipmedia -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sipmedia}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sipmedia/config, to reflect the network for the SIP Media container<br />
<br />
{{cat|/var/lib/lxc/sipmedia/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.sipmedia}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sipmedia}}<br />
<br />
== Enter the SIP Media container ==<br />
{{Cmd|lxc-console -n sipmedia}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%B2BUA_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
TO POPULATE<br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
= Install the WiFi Web Proxy Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WIFI_IP_ADDRESS%><br />
netmask <%VPNc_WIFI_NETMASK%><br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address <%WIFI_TRANSIT_IP_ADDRESS%><br />
netmask <%WIFI_TRANSIT_NETMASK%><br />
gateway <%DMVPN_WIFI_TRANSIT_IP_ADDRESS%><br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address <%WIFI_MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10097
Small Office Services
2014-07-20T20:17:47Z
<p>Jbilyk: /* Install the wifi Container */</p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
The assumption is made that the following VLANs and subnets are used as the DMVPN document did:<br />
<br />
{|class="wikitable"<br />
!'''Interface'''<br />
!'''Description'''<br />
!'''Subnet'''<br />
|-<br />
|bond0.3<br />
|Management<br />
|10.1.0.129/26<br />
|-<br />
|bond0.101<br />
|LAN<br />
|10.1.0.0/25<br />
|-<br />
|bond0.256<br />
|Internet from ISP1<br />
|Allocated from ISP<br />
|-<br />
|bond0.257<br />
|Internet from ISP2<br />
|Allocated from ISP<br />
|-<br />
|bond0.620<br />
|Transit between wifi proxy and dmvpn spoke node<br />
|10.1.0.252/30<br />
|-<br />
|bond0.701<br />
|WiFi clients (no access to DMVPN network)<br />
|172.17.48.0/24<br />
|-<br />
|bond0.1101<br />
|Voice<br />
|10.2.0.0/24<br />
|}<br />
<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.2<br />
netmask 255.255.255.192<br />
gateway 10.1.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$10.1.0.2",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth_3<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth_701<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth_1101<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Voice VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address <%DHCPDNS_VOICE_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
up ip address add <%DHCPDNS_VOIP_IP_ADDRESS2%>/25 dev eth0<br />
#Management VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address <%MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
<br />
<br />
#WiFi VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address <%DHCPDNS_WIFI_IP_ADDRESS%><br />
netmask <%WIFI_NETMASK%><br />
<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers <%DMVPN_VOICE_IP_ADDRESS%>;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet <%VOICE_SUBNET%> netmask <%VOICE_NETMASK%><br />
{<br />
range <%VOICE_DHCP_RANGE%>;<br />
option domain-name-servers <%DHCPDNS_VOICE_IP_ADDRESS%>;<br />
option routers <%DMVPN_VOICE_IP_ADDRESS%>;<br />
option boot-server "http://<%SIP_IP_ADDRESS%>";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet <%WIFI_SUBNET%> netmask <%WIFI_NETMASK%><br />
{<br />
range <%WIFI_DHCP_RANGE%>;<br />
option routers <%WIFI_PROXY_IP_ADDRESS%>;<br />
option domain-name-servers <%DHCPDNS_WIFI_IP_ADDRESS%>; <br />
option domain-name "<%WIFI_DOMAIN%>";<br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: <%DHCPDNS_VOICE_IP_ADDRESS%><br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: <%DHCPDNS_VOICE_IP_ADDRESS2%><br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver <%DHCPDNS_VOICE_IP_ADDRESS%> > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: <%DHCPDNS_VOICE_IP_ADDRESS2%><br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A <%DHCPDNS_VOICE_IP_ADDRESS%><br />
<br />
;A Records for SIP Devices<br />
sip IN A <%SIP_IP_ADDRESS%><br />
map IN A <%VMAIL_IP_ADDRESS%><br />
<br />
;NAPTR Records<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.vmail.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp IN SRV 10 1 5060 sip<br />
_sip._udp IN SRV 10 1 5060 vmail<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%SIP_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'listen_addresses', and the 'log_destination' variables to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
listen_addresses {{=}}'<%SIP_IP_ADDRESS%><br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
<br />
== Install acf-provisioning ==<br />
TO POPULATE<br />
<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the SIP Media container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sipmedia -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sipmedia}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sipmedia/config, to reflect the network for the SIP Media container<br />
<br />
{{cat|/var/lib/lxc/sipmedia/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.sipmedia}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sipmedia}}<br />
<br />
== Enter the SIP Media container ==<br />
{{Cmd|lxc-console -n sipmedia}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%B2BUA_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
TO POPULATE<br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
= Install the WiFi Web Proxy Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WIFI_IP_ADDRESS%><br />
netmask <%VPNc_WIFI_NETMASK%><br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address <%WIFI_TRANSIT_IP_ADDRESS%><br />
netmask <%WIFI_TRANSIT_NETMASK%><br />
gateway <%DMVPN_WIFI_TRANSIT_IP_ADDRESS%><br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address <%WIFI_MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10096
Small Office Services
2014-07-20T20:17:14Z
<p>Jbilyk: /* Enter the webproxy container */</p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
The assumption is made that the following VLANs and subnets are used as the DMVPN document did:<br />
<br />
{|class="wikitable"<br />
!'''Interface'''<br />
!'''Description'''<br />
!'''Subnet'''<br />
|-<br />
|bond0.3<br />
|Management<br />
|10.1.0.129/26<br />
|-<br />
|bond0.101<br />
|LAN<br />
|10.1.0.0/25<br />
|-<br />
|bond0.256<br />
|Internet from ISP1<br />
|Allocated from ISP<br />
|-<br />
|bond0.257<br />
|Internet from ISP2<br />
|Allocated from ISP<br />
|-<br />
|bond0.620<br />
|Transit between wifi proxy and dmvpn spoke node<br />
|10.1.0.252/30<br />
|-<br />
|bond0.701<br />
|WiFi clients (no access to DMVPN network)<br />
|172.17.48.0/24<br />
|-<br />
|bond0.1101<br />
|Voice<br />
|10.2.0.0/24<br />
|}<br />
<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address 10.1.0.2<br />
netmask 255.255.255.192<br />
gateway 10.1.0.1<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$10.1.0.2",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth_3<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth_701<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth_1101<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Voice VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address <%DHCPDNS_VOICE_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
up ip address add <%DHCPDNS_VOIP_IP_ADDRESS2%>/25 dev eth0<br />
#Management VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address <%MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
<br />
<br />
#WiFi VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address <%DHCPDNS_WIFI_IP_ADDRESS%><br />
netmask <%WIFI_NETMASK%><br />
<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers <%DMVPN_VOICE_IP_ADDRESS%>;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet <%VOICE_SUBNET%> netmask <%VOICE_NETMASK%><br />
{<br />
range <%VOICE_DHCP_RANGE%>;<br />
option domain-name-servers <%DHCPDNS_VOICE_IP_ADDRESS%>;<br />
option routers <%DMVPN_VOICE_IP_ADDRESS%>;<br />
option boot-server "http://<%SIP_IP_ADDRESS%>";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet <%WIFI_SUBNET%> netmask <%WIFI_NETMASK%><br />
{<br />
range <%WIFI_DHCP_RANGE%>;<br />
option routers <%WIFI_PROXY_IP_ADDRESS%>;<br />
option domain-name-servers <%DHCPDNS_WIFI_IP_ADDRESS%>; <br />
option domain-name "<%WIFI_DOMAIN%>";<br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: <%DHCPDNS_VOICE_IP_ADDRESS%><br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: <%DHCPDNS_VOICE_IP_ADDRESS2%><br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver <%DHCPDNS_VOICE_IP_ADDRESS%> > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: <%DHCPDNS_VOICE_IP_ADDRESS2%><br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A <%DHCPDNS_VOICE_IP_ADDRESS%><br />
<br />
;A Records for SIP Devices<br />
sip IN A <%SIP_IP_ADDRESS%><br />
map IN A <%VMAIL_IP_ADDRESS%><br />
<br />
;NAPTR Records<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.vmail.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp IN SRV 10 1 5060 sip<br />
_sip._udp IN SRV 10 1 5060 vmail<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%SIP_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'listen_addresses', and the 'log_destination' variables to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
listen_addresses {{=}}'<%SIP_IP_ADDRESS%><br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
<br />
== Install acf-provisioning ==<br />
TO POPULATE<br />
<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the SIP Media container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sipmedia -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sipmedia}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sipmedia/config, to reflect the network for the SIP Media container<br />
<br />
{{cat|/var/lib/lxc/sipmedia/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.sipmedia}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sipmedia}}<br />
<br />
== Enter the SIP Media container ==<br />
{{Cmd|lxc-console -n sipmedia}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%B2BUA_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
TO POPULATE<br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
= Install the wifi Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WIFI_IP_ADDRESS%><br />
netmask <%VPNc_WIFI_NETMASK%><br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address <%WIFI_TRANSIT_IP_ADDRESS%><br />
netmask <%WIFI_TRANSIT_NETMASK%><br />
gateway <%DMVPN_WIFI_TRANSIT_IP_ADDRESS%><br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address <%WIFI_MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10095
Small Office Services
2014-07-20T20:10:24Z
<p>Jbilyk: </p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
The assumption is made that the following VLANs and subnets are used as the DMVPN document did:<br />
<br />
{|class="wikitable"<br />
!'''Interface'''<br />
!'''Description'''<br />
!'''Subnet'''<br />
|-<br />
|bond0.3<br />
|Management<br />
|10.1.0.129/26<br />
|-<br />
|bond0.101<br />
|LAN<br />
|10.1.0.0/25<br />
|-<br />
|bond0.256<br />
|Internet from ISP1<br />
|Allocated from ISP<br />
|-<br />
|bond0.257<br />
|Internet from ISP2<br />
|Allocated from ISP<br />
|-<br />
|bond0.620<br />
|Transit between wifi proxy and dmvpn spoke node<br />
|10.1.0.252/30<br />
|-<br />
|bond0.701<br />
|WiFi clients (no access to DMVPN network)<br />
|172.17.48.0/24<br />
|-<br />
|bond0.1101<br />
|Voice<br />
|10.2.0.0/24<br />
|}<br />
<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WEB_PROXY_IP_ADDRESS%><br />
netmask <%DMVPN_LAN_NETMASK%><br />
gateway <%DMVPN_LAN_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$WEB_PROXY",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth_3<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth_701<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth_1101<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Voice VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address <%DHCPDNS_VOICE_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
up ip address add <%DHCPDNS_VOIP_IP_ADDRESS2%>/25 dev eth0<br />
#Management VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address <%MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
<br />
<br />
#WiFi VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address <%DHCPDNS_WIFI_IP_ADDRESS%><br />
netmask <%WIFI_NETMASK%><br />
<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers <%DMVPN_VOICE_IP_ADDRESS%>;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet <%VOICE_SUBNET%> netmask <%VOICE_NETMASK%><br />
{<br />
range <%VOICE_DHCP_RANGE%>;<br />
option domain-name-servers <%DHCPDNS_VOICE_IP_ADDRESS%>;<br />
option routers <%DMVPN_VOICE_IP_ADDRESS%>;<br />
option boot-server "http://<%SIP_IP_ADDRESS%>";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet <%WIFI_SUBNET%> netmask <%WIFI_NETMASK%><br />
{<br />
range <%WIFI_DHCP_RANGE%>;<br />
option routers <%WIFI_PROXY_IP_ADDRESS%>;<br />
option domain-name-servers <%DHCPDNS_WIFI_IP_ADDRESS%>; <br />
option domain-name "<%WIFI_DOMAIN%>";<br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: <%DHCPDNS_VOICE_IP_ADDRESS%><br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: <%DHCPDNS_VOICE_IP_ADDRESS2%><br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver <%DHCPDNS_VOICE_IP_ADDRESS%> > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: <%DHCPDNS_VOICE_IP_ADDRESS2%><br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A <%DHCPDNS_VOICE_IP_ADDRESS%><br />
<br />
;A Records for SIP Devices<br />
sip IN A <%SIP_IP_ADDRESS%><br />
map IN A <%VMAIL_IP_ADDRESS%><br />
<br />
;NAPTR Records<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.vmail.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp IN SRV 10 1 5060 sip<br />
_sip._udp IN SRV 10 1 5060 vmail<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%SIP_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'listen_addresses', and the 'log_destination' variables to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
listen_addresses {{=}}'<%SIP_IP_ADDRESS%><br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the B2BUA container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n b2bua -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.b2bua}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/b2bua/config, to reflect the network for the B2BUA container<br />
<br />
{{cat|/var/lib/lxc/b2bua/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.b2bua}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.b2bua}}<br />
<br />
== Enter the B2BUA container ==<br />
{{Cmd|lxc-console -n b2bua}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%B2BUA_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
<?xml version="1.0"?><br />
<document type="freeswitch/xml"><br />
<br />
<!-- Variables we need to set --><br />
<br />
<X-PRE-PROCESS cmd="set" data="b2bua=<%B2BUA_IP_ADDRESS%>"/><br />
<X-PRE-PROCESS cmd="set" data="domain=office.example.net"/><br />
<X-PRE-PROCESS cmd="set" data="siprouter=office.example.net"/><br />
<br />
<!-- Variables we don´t need to set --><br />
<br />
<!-- External SIP Profile --><br />
<X-PRE-PROCESS cmd="set" data="external_sip_port=5060"/><br />
<!-- Glogal codecs --><br />
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=G7221@32000h,G7221@16000h,G722,PCMU,PCMA,GSM"/><br />
<!-- Outbound codecs --><br />
<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=PCMU,PCMA,GSM"/><br />
<br />
<section name="configuration" description="Various Configuration"><br />
<br />
<configuration name="modules.conf" description="Modules"><br />
<modules><br />
<load module="mod_commands"/><br />
<load module="mod_console"/><br />
<load module="mod_dptools"/><br />
<load module="mod_dialplan_xml"/><br />
<load module="mod_event_socket"/><br />
<load module="mod_logfile"/><br />
<load module="mod_sofia"/><br />
</modules><br />
</configuration><br />
<br />
<configuration name="console.conf" description="Console Logger"><br />
<mappings><br />
<map name="all" value="console,debug,info,notice,warning,err,crit,alert"/><br />
</mappings><br />
<settings><br />
<param name="loglevel" value="info"/><br />
</settings><br />
</configuration><br />
<br />
<configuration name="logfile.conf" description="File Logging"><br />
<settings><br />
<param name="rotate-on-hup" value="true"/><br />
</settings><br />
<profiles><br />
<profile name="default"><br />
<settings><br />
<param name="rollover" value="10485760"/><br />
</settings><br />
<mappings><br />
<map name="all" value="debug,info,notice,warning,err,crit,alert"/><br />
</mappings><br />
</profile><br />
</profiles><br />
</configuration><br />
<br />
<configuration name="sofia.conf" description="sofia Endpoint"><br />
<global_settings><br />
<param name="log-level" value="0"/><br />
<param name="debug-presence" value="0"/><br />
<param name="debug" value="0"/><br />
<param name="sip-trace" value="no"/><br />
<param name="log-auth-failures" value="false"/><br />
<param name="forward-unsolicited-mwi-notify" value="false"/><br />
<param name="rfc2833-pt" value="101"/><br />
<param name="sip-port" value="5060"/><br />
<param name="dialplan" value="XML"/><br />
<param name="dtmf-duration" value="2000"/><br />
<param name="rtp-timer-name" value="soft"/><br />
<param name="inbound-codec-negotiation" value="generous"/><br />
<param name="tls" value="false"/><br />
<param name="nonce-ttl" value="60"/><br />
<param name="auth-calls" value="false"/><br />
<param name="auth-all-packets" value="false"/><br />
<param name="rtp-timeout-sec" value="300"/><br />
<param name="rtp-hold-timeout-sec" value="1800"/><br />
<param name="challenge-realm" value="auto_from"/><br />
</global_settings><br />
<br />
<profiles><br />
<profile name="$${domain}"><br />
<domains><br />
<domain name="all" alias="false" parse="true"/><br />
</domains><br />
<settings><br />
<param name="debug" value="0"/><br />
<param name="sip-trace" value="no"/><br />
<param name="rfc2833-pt" value="101"/><br />
<param name="sip-port" value="$${external_sip_port}"/><br />
<param name="dialplan" value="XML"/><br />
<param name="context" value="default"/><br />
<param name="dtmf-duration" value="2000"/><br />
<param name="inbound-codec-prefs" value="$${global_codec_prefs}"/><br />
<param name="outbound-codec-prefs" value="$${outbound_codec_prefs}"/><br />
<param name="rtp-timer-name" value="soft"/><br />
<param name="local-network-acl" value="rfc1918.auto"/><br />
<param name="manage-presence" value="false"/><br />
<param name="inbound-codec-negotiation" value="generous"/><br />
<param name="nonce-ttl" value="60"/><br />
<param name="auth-calls" value="false"/><br />
<param name="rtp-ip" value="$${b2bua}"/><br />
<param name="sip-ip" value="$${b2bua}"/><br />
<param name="tls" value="false"/><br />
</settings><br />
</profile> <br />
</profiles> <br />
<br />
</configuration><br />
<br />
<configuration name="switch.conf" description="Core Configuration"><br />
<br />
<cli-keybindings><br />
<key name="1" value="help"/><br />
<key name="2" value="status"/><br />
<key name="3" value="show channels"/><br />
<key name="4" value="show calls"/><br />
<key name="5" value="sofia status"/><br />
<key name="6" value="reloadxml"/><br />
</cli-keybindings><br />
<br />
<settings><br />
<param name="colorize-console" value="true"/><br />
<param name="max-sessions" value="1000"/><br />
<param name="sessions-per-second" value="30"/><br />
<param name="loglevel" value="debug"/><br />
<param name="dump-cores" value="yes"/><br />
<param name="rtp-enable-zrtp" value="false"/><br />
<param name="rtp-start-port" value="13000"/><br />
<param name="rtp-end-port" value="18000"/><br />
</settings><br />
</configuration><br />
<br />
<configuration name="post_load_modules.conf" description="Post-load modules"/><br />
<br />
</section><br />
<br />
<!-- Incomming Calls --><br />
<section name="dialplan" description="Regex/XML Dialplan"><br />
<context name="default"><br />
<extension name="b2b-in"><br />
<condition field="destination_number" expression="^(\d*)$"><br />
<action application="set" data="ringback=%(2000,4000,440.0,480.0)"/><br />
<action application="set" data="hangup_after_bridge=true"/><br />
<action application="set" data="continue_on_fail=true"/><br />
<action application="set" data="ignore_early_media=true"/> <br />
<action application="set" data="bypass_media=true"/> <br />
<action application="answer"/><br />
<action application="sleep" data="1000"/><br />
<action application="unset" data="sip_h_P-ARP"/><br />
<action application="bridge" data="sofia/$${domain}/$1@$${siprouter}"/><br />
</condition><br />
</extension><br />
</context> <br />
</section><br />
</document><br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
= Install the wifi Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WIFI_IP_ADDRESS%><br />
netmask <%VPNc_WIFI_NETMASK%><br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address <%WIFI_TRANSIT_IP_ADDRESS%><br />
netmask <%WIFI_TRANSIT_NETMASK%><br />
gateway <%DMVPN_WIFI_TRANSIT_IP_ADDRESS%><br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address <%WIFI_MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10094
Small Office Services
2014-07-20T20:08:18Z
<p>Jbilyk: </p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.620<br />
iface bond0.620 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WEB_PROXY_IP_ADDRESS%><br />
netmask <%DMVPN_LAN_NETMASK%><br />
gateway <%DMVPN_LAN_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$WEB_PROXY",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth_3<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth_701<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth_1101<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Voice VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address <%DHCPDNS_VOICE_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
up ip address add <%DHCPDNS_VOIP_IP_ADDRESS2%>/25 dev eth0<br />
#Management VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address <%MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
<br />
<br />
#WiFi VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address <%DHCPDNS_WIFI_IP_ADDRESS%><br />
netmask <%WIFI_NETMASK%><br />
<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers <%DMVPN_VOICE_IP_ADDRESS%>;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet <%VOICE_SUBNET%> netmask <%VOICE_NETMASK%><br />
{<br />
range <%VOICE_DHCP_RANGE%>;<br />
option domain-name-servers <%DHCPDNS_VOICE_IP_ADDRESS%>;<br />
option routers <%DMVPN_VOICE_IP_ADDRESS%>;<br />
option boot-server "http://<%SIP_IP_ADDRESS%>";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet <%WIFI_SUBNET%> netmask <%WIFI_NETMASK%><br />
{<br />
range <%WIFI_DHCP_RANGE%>;<br />
option routers <%WIFI_PROXY_IP_ADDRESS%>;<br />
option domain-name-servers <%DHCPDNS_WIFI_IP_ADDRESS%>; <br />
option domain-name "<%WIFI_DOMAIN%>";<br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: <%DHCPDNS_VOICE_IP_ADDRESS%><br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: <%DHCPDNS_VOICE_IP_ADDRESS2%><br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver <%DHCPDNS_VOICE_IP_ADDRESS%> > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: <%DHCPDNS_VOICE_IP_ADDRESS2%><br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A <%DHCPDNS_VOICE_IP_ADDRESS%><br />
<br />
;A Records for SIP Devices<br />
sip IN A <%SIP_IP_ADDRESS%><br />
map IN A <%VMAIL_IP_ADDRESS%><br />
<br />
;NAPTR Records<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.vmail.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp IN SRV 10 1 5060 sip<br />
_sip._udp IN SRV 10 1 5060 vmail<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%SIP_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'listen_addresses', and the 'log_destination' variables to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
listen_addresses {{=}}'<%SIP_IP_ADDRESS%><br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
<br />
==Install ACF-Provisioning==<br />
<br />
TO POPULATE<br />
<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the SIP Media container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n media -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.media}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/media/config, to reflect the network for the SIP Media container<br />
<br />
{{cat|/var/lib/lxc/media/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.media}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.media}}<br />
<br />
== Enter the SIP Media container ==<br />
{{Cmd|lxc-console -n media}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%SIP_MEDIA_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
TO POPULATE<br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
<br />
= Install the wifi Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WIFI_IP_ADDRESS%><br />
netmask <%VPNc_WIFI_NETMASK%><br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address <%WIFI_TRANSIT_IP_ADDRESS%><br />
netmask <%WIFI_TRANSIT_NETMASK%><br />
gateway <%DMVPN_WIFI_TRANSIT_IP_ADDRESS%><br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address <%WIFI_MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=10093
Dynamic Multipoint VPN (DMVPN)
2014-07-20T20:01:37Z
<p>Jbilyk: /* Alpine Setup */ adjust IP addressing</p>
<hr />
<div>http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, firewall, etc.). [[Small Office Services]] offers additional services such as DHCP for clients, http proxying, and a basic SIP telephone system.<br />
<br />
= Terminology =<br />
;NBMA: ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
;Hub: the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
;Spoke: the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Hardware =<br />
If you are looking for hundreds of megabits of throughput for your VPN with a limited budget, you should consider using [http://www.via.com.tw/en/initiatives/padlock/hardware.jsp VIA Padlock] engine present in VIA processor C7, Eden, Nano and Quad. If you need gigabits throughput you should go instead for an Intel Xeon processor with [http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-instructions-aes-ni AES-NI] and [http://software.intel.com/en-us/articles/intel-sha-extensions SHA Extensions]<br />
<br />
For supporting VIA Padlock engine enable its modules:<br />
<br />
{{Cmd|echo -e "padlock_aes\npadlock-sha" >> /etc/modules}}<br />
<br />
= Extract Certificates =<br />
We will use certificates for DMVPN and for OpenVPN (RoadWarrior clients). If you are in need to generate your own certificates, please see [[Generating_SSL_certs_with_ACF]]. You should use a separate machine for this purpose. If you downloaded the certificates on a Windows machine, you may use [http://winscp.net/eng/download.php WinSCP] to copy them on the DMVPN box.<br />
<br />
Here are the general purpose instruction for extracting certificates from pfx files:<br />
<br />
{{Cmd|openssl pkcs12 -in cert.pfx -cacerts -nokeys -out cacert.pem<br />
openssl pkcs12 -in cert.pfx -nocerts -nodes -out serverkey.pem<br />
openssl pkcs12 -in cert.pfx -nokeys -clcerts -out cert.pem<br />
}}<br />
<br />
Set appropriate permission for your certificate files:<br />
<br />
{{Cmd|chmod 600 *.pem *.pfx}}<br />
<br />
= Spoke Node =<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
{|class="wikitable"<br />
!'''Interface'''<br />
!'''Description'''<br />
!'''Subnet'''<br />
|-<br />
|bond0.3<br />
|Management<br />
|10.1.0.129/26<br />
|-<br />
|bond0.101<br />
|LAN<br />
|10.1.0.0/25<br />
|-<br />
|bond0.256<br />
|Internet from ISP1<br />
|Allocated from ISP<br />
|-<br />
|bond0.257<br />
|Internet from ISP2<br />
|Allocated from ISP<br />
|-<br />
|bond0.620<br />
|Transit between wifi proxy and dmvpn spoke node<br />
|10.1.0.252/30<br />
|-<br />
|bond0.701<br />
|WiFi clients (no access to DMVPN network)<br />
|172.17.48.0/24<br />
|-<br />
|bond0.1101<br />
|Voice<br />
|10.2.0.0/24<br />
|}<br />
<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.101'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.101? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.101 configuration for bond0.620, bond0.701, bond0.1101, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Networking ==<br />
Update the networking configuration.<br />
<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add interfaces:<br />
<br />
{{cat|/etc/network/interfaces|<br />
...<br />
<br />
auto bond0.101<br />
iface bond0.101 inet static<br />
address 10.1.0.1<br />
netmask 255.255.255.192<br />
<br />
auto bond0.620<br />
iface bond0.620 inet static<br />
address 10.1.0.253<br />
netmask 255.255.255.252<br />
<br />
auto bond0.701<br />
iface bond0.101 inet static<br />
address 172.17.48.1<br />
netmask 255.255.255.0<br />
<br />
auto bond0.1101<br />
iface bond0.101 inet static<br />
address 10.2.0.1<br />
netmask 255.255.255.0<br />
<br />
auto bond0.256<br />
iface bond0.256 inet static<br />
address <%ISP1_IP_ADDRESS%><br />
netmask <%ISP1_NETMASK%><br />
<br />
auto bond0.257<br />
iface bond0.257 inet static<br />
address <%ISP2_IP_ADDRESS%><br />
netmask <%ISP2_NETMASK%><br />
}}<br />
<br />
== Bonding ==<br />
Update the bonding configuration.<br />
<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add <code>bond-mode</code>, <code>bond-miimon</code> and <code>bond-updelay</code> parameters to the <code>bond0</code> stanza:<br />
<br />
{{cat|/etc/network/interfaces|<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
...<br />
}}<br />
<br />
Bring up the new bonding settings:<br />
<br />
{{Cmd|ifdown bond0<br />
ifup bond0}}<br />
<br />
<br />
== Physically install ==<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to <code>eth0</code>. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== SSH ==<br />
Remove password authentication and DNS reverse lookup:<br />
<br />
{{Cmd|sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Restart ssh:<br />
{{Cmd|/etc/init.d/sshd restart}}<br />
<br />
== NTP server ==<br />
In order to have attached devices syncing their time agains this host, we need to do some modifications to chrony config.<BR><br />
Add '<code>allow all</code>' to the end of the '<code>/etc/chrony/chrony.conf</code>' so the file looks something like this:<br />
<br />
{{cat|/etc/chrony/chrony.conf|<br />
server pool.ntp.org <br />
initstepslew 10 pool.ntp.org<br />
commandkey 10<br />
keyfile /etc/chrony/chrony.keys<br />
driftfile /etc/chrony/chrony.drift<br />
allow all<br />
}}<br />
<br />
Restart chronyd for the changes to take effect<br />
{{cmd|/etc/init.d/chronyd restart}}<br />
<br />
== Recursive DNS ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add -U unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<br />
{{cat|/etc/unbound/unbound.conf|<br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
}}<br />
<br />
Start unbound and start using unbound on this host:<br />
<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
{{cat|/etc/network/interfaces|<nowiki><br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
</nowiki>}}<br />
<br />
Bring up the new <code>gre1</code> interface:<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor create <code>/etc/ipsec.conf</code> and set the content to the following:<br />
<br />
{{cat|/etc/ipsec.conf|<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
}}<br />
<br />
Create missing directory:<br />
<br />
{{Cmd|mkdir /etc/racoon/}}<br />
<br />
Extract your pfx into <code>/etc/racoon</code>, using the filenames '''<code>ca.pem</code>''', '''<code>cert.pem</code>''', and '''<code>key.pem</code>''' (see [[Dynamic_Multipoint_VPN_%28DMVPN%29#Extract_Certificates|instructions above]] for command).<br />
<br />
With your favorite editor create <code>/etc/racoon/racoon.conf</code> and set the content to the following:<br />
<br />
{{cat|/etc/racoon/racoon.conf|<br />
path certificate "/etc/racoon/";<br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
}}<br />
<br />
Edit <code>/etc/conf.d/racoon</code> and unset <code>RACOON_PSK_FILE</code>:<br />
<br />
{{cat|/etc/conf.d/racoon|<br />
...<br />
RACOON_PSK_FILE{{=}}<br />
...<br />
}}<br />
<br />
Start service(s):<br />
<br />
{{Cmd|/etc/init.d/racoon start<br />
rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
{{cat|/etc/opennhrp/opennhrp.conf|<br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
<br />
interface bond0.620<br />
shortcut-destination<br />
}}<br />
<br />
You must have a DNS A record ''<code>hub.example.com</code>'' for each hub node IP address.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
{{cat|/etc/opennhrp/opennhrp-script|<nowiki>#!/bin/sh<br />
<br />
MYAS=$(sed -n 's/router bgp \(\d*\)/\1/p' < /etc/quagga/bgpd.conf)<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</nowiki>}}<br />
<br />
Make it executable and start service(s):<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script<br />
/etc/init.d/opennhrp start<br />
rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add quagga<br />
touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following (replace <code>strongpassword</code> with a password of your choice and <code>%HUB_GRE_IP%</code> with the '''Hub''' node GRE IP address):<br />
* Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
{{cat|/etc/quagga/bgpd.conf|<br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
}}<br />
<br />
Start service(s):<br />
<br />
{{Cmd|/etc/init.d/bgpd start<br />
rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
Install package(s):<br />
<br />
{{Cmd|echo tun >> /etc/modules<br />
modprobe tun<br />
apk add openvpn openssl<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024}}<br />
<br />
Configure openvpn:<br />
<br />
{{cat|/etc/openvpn/openvpn.conf|<br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
}}<br />
<br />
Start service(s):<br />
<br />
{{Cmd|/etc/init.d/openvpn start<br />
rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add awall}}<br />
<br />
Enable IP forwarding:<br />
<br />
{{Cmd|sysctl -w net.ipv4.ip_forward{{=}}1<br />
sed -i 's/.*net\.ipv4\.ip_forward.*$/net.ipv4.ip_forward {{=}} 1/g' /etc/sysctl.conf}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
{{cat|/etc/awall/optional/params.json|<br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF": "bond0.8",<br />
"C_IF": "bond0.64",<br />
"DE_IF": "bond0.620",<br />
"ISP1_IF": "bond0.256",<br />
"ISP2_IF": "bond0.257"<br />
}<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/internet-host.json|<br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/openvpn.json|<br />
{<br />
"description": "OpenVPN support",<br />
<br />
"import": "internet-host",<br />
<br />
"service": { <br />
"openvpn": { "proto": "udp", "port": 1194 }<br />
},<br />
<br />
"filter": [ <br />
{ "in": "E", "out": "_fw", "service": "openvpn", "action": "accept" }<br />
]<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/clampmss.json|<br />
{<br />
"description": "Deal with ISPs afraid of ICMP",<br />
<br />
"import": "internet-host",<br />
<br />
"clamp-mss": [ { "out": "E" } ]<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/mark.json|<br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/dmvpn.json|<br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
}}<br />
<br />
{{cat|/etc/awall/optional/vpnc.json|<br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" },<br />
"DE": { "iface": "$DE_IF" }<br />
<br />
},<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "DE", "out": "E", "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"out": "DE",<br />
"service": [ "ssh", "http", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
}}<br />
<br />
Activate the firewall:<br />
<br />
{{Cmd|modprobe ip_tables<br />
modprobe iptable_nat <br />
awall enable clampmss<br />
awall enable openvpn<br />
awall enable vpnc<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add pingu<br />
echo -e "1\tisp1">> /etc/iproute2/rt_tables<br />
echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
Configure pingu to monitor our <code>bond0.256</code> and <code>bond0.257</code> interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<br />
{{cat|/etc/pingu/pingu.conf|<br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
fwmark 1<br />
rule-priority 20000<br />
# google dns<br />
ping 8.8.8.8<br />
# opendns<br />
ping 208.67.222.222<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
fwmark 2<br />
rule-priority 20000<br />
}<br />
}}<br />
<br />
Make sure we can reach the public IP from our LAN by adding static route rules for our private net(s). Edit <code>/etc/pingu/route-rules</code>:<br />
<br />
{{cat|/etc/pingu/route-rules|<br />
to 10.0.0.0/8 table main prio 1000<br />
to 172.16.0.0/12 table main prio 1000<br />
}}<br />
<br />
Start service(s):<br />
<br />
{{Cmd|/etc/init.d/pingu start<br />
rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via <code>bond0.256</code> so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
Commit configuration:<br />
<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
We will document only what changes from the Spoke node setup.<br />
<br />
== Routing Tables ==<br />
{{Todo|Would we need to change this command - or add some description on why it's documented?}}<br />
<br />
{{Cmd|echo -e "42\tnhrp_shortcut\n43\tnhrp_mtu\n44\tquagga\n}}<br />
<br />
== NHRP ==<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> on Hub 2 and set the content as follows:<br />
<br />
{{cat|/etc/opennhrp/opennhrp.conf|<br />
interface gre1<br />
map %Hub1_GRE_IP%/%MaskBit% hub1.example.org<br />
route-table 44<br />
shortcut<br />
redirect<br />
non-caching<br />
}}<br />
<br />
Do the same on Hub 1 adding the data relative to Hub 2.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and set the content as follows:<br />
<br />
<pre><br />
#!/bin/sh<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -t opennhrp-script -p auth.err "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
logger -t opennhrp-script -p auth.info "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA authenticated"<br />
<br />
(<br />
flock -x 200<br />
<br />
AS=`echo "$CERT" | grep "^AS=" | cut -b 4-`<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "router bgp 65000" \<br />
-c "neighbor $NHRP_DESTADDR remote-as $AS" \<br />
-c "neighbor $NHRP_DESTADDR peer-group leaf" \<br />
-c "neighbor $NHRP_DESTADDR prefix-list net-$AS-in in"<br />
<br />
SEQ=5<br />
(echo "$CERT" | grep "^NET=" | cut -b 5-) | while read NET; do<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "ip prefix-list net-$AS-in seq $SEQ permit $NET le 26"<br />
SEQ=$(($SEQ+5))<br />
done<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
peer-up)<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -p daemon.err "GRE mapping of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU table nhrp_mtu<br />
fi<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42 table nhrp_mtu<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</pre><br />
<br />
== BGP ==<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> on Hub 2 and set the content as follows:<br />
<br />
{{cat|/etc/quagga/bgpd.conf|<br />
password zebra<br />
enable password zebra<br />
log syslog<br />
<br />
router bgp 65000<br />
bgp router-id %Hub2_GRE_IP%<br />
bgp deterministic-med<br />
network %GRE_NETWORK%/%MASK_BITS%<br />
neighbor hub peer-group<br />
neighbor hub next-hop-self<br />
neighbor hub route-map CORE-IN in<br />
neighbor spoke peer-group<br />
neighbor spoke passive<br />
neighbor spoke next-hop-self<br />
neighbor %Spoke1_GRE_IP% remote-as 65001<br />
neighbor %Spoke1_GRE_IP% peer-group spoke<br />
neighbor %Spoke1_GRE_IP% prefix-list net-65001-in in<br />
...<br />
...<br />
...<br />
<br />
neighbor hub remote-as 65000<br />
neighbor %Hub1_GRE_IP% peer-group core<br />
<br />
ip prefix-list net-65001-in seq 5 permit 10.1.0.0/16 le 26<br />
...<br />
<br />
route-map CORE-IN permit 10<br />
set metric +100<br />
}}<br />
<br />
Add the lines <code>neighbor %Spoke1_GRE_IP%...</code> for each spoke node you have. Do the same on Hub 1, changing the relevant data for Hub 2.<br />
<br />
= Troubleshooting the DMVPN =<br />
== Broken [http://en.wikipedia.org/wiki/Path_MTU_Discovery Path MTU Discovery (PMTUD)] ==<br />
ISPs afraid of ICMP (which is somehow legitimate) often just blindly add <code>no ip unreachables</code> in their router interfaces, effectively creating a [http://en.wikipedia.org/wiki/Black_hole_%28networking%29 blackhole router] that breaks PMTUD, since ICMP Type 3 Code 4 packets (Fragmentation Needed) are dropped. PMTUD is needed by ISAKMP that runs on UDP (TCP works because it uses CLAMPMSS).<br />
<br />
For technical details see http://packetlife.net/blog/2008/oct/9/disabling-unreachables-breaks-pmtud/<br />
<br />
PMTUD could also be broken due to badly configured DSL modem/routers or bugged firmware. Turning off the firewall on modem itself or any VPN passthrough functionality it may help.<br />
<br />
You can easily detect which host is the blackhole router by pinging with DF bit set and with packets of standard MTU size, each hop given in your traceroute to destination:<br />
<br />
{{Cmd|ping -M do -s 1472 %IP%}}<br />
{{Note|"-M do" requires GNU ping, present in <code>iputils</code> package}}<br />
<br />
If you don't get a response back (either Echo-Response or Fragmentation-Needed) there's firewall dropping ICMP packets. If it answers to normal ping packets (DF bit cleared), most likely you have hit a blackhole router.<br />
<br />
== Kernel and NHRP Routing Cache Issues ==<br />
{{Todo|...}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=10092
Dynamic Multipoint VPN (DMVPN)
2014-07-20T19:50:46Z
<p>Jbilyk: /* Alpine Setup */ adjust vlan id</p>
<hr />
<div>http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, firewall, etc.). [[Small Office Services]] offers additional services such as DHCP for clients, http proxying, and a basic SIP telephone system.<br />
<br />
= Terminology =<br />
;NBMA: ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
;Hub: the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
;Spoke: the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Hardware =<br />
If you are looking for hundreds of megabits of throughput for your VPN with a limited budget, you should consider using [http://www.via.com.tw/en/initiatives/padlock/hardware.jsp VIA Padlock] engine present in VIA processor C7, Eden, Nano and Quad. If you need gigabits throughput you should go instead for an Intel Xeon processor with [http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-instructions-aes-ni AES-NI] and [http://software.intel.com/en-us/articles/intel-sha-extensions SHA Extensions]<br />
<br />
For supporting VIA Padlock engine enable its modules:<br />
<br />
{{Cmd|echo -e "padlock_aes\npadlock-sha" >> /etc/modules}}<br />
<br />
= Extract Certificates =<br />
We will use certificates for DMVPN and for OpenVPN (RoadWarrior clients). If you are in need to generate your own certificates, please see [[Generating_SSL_certs_with_ACF]]. You should use a separate machine for this purpose. If you downloaded the certificates on a Windows machine, you may use [http://winscp.net/eng/download.php WinSCP] to copy them on the DMVPN box.<br />
<br />
Here are the general purpose instruction for extracting certificates from pfx files:<br />
<br />
{{Cmd|openssl pkcs12 -in cert.pfx -cacerts -nokeys -out cacert.pem<br />
openssl pkcs12 -in cert.pfx -nocerts -nodes -out serverkey.pem<br />
openssl pkcs12 -in cert.pfx -nokeys -clcerts -out cert.pem<br />
}}<br />
<br />
Set appropriate permission for your certificate files:<br />
<br />
{{Cmd|chmod 600 *.pem *.pfx}}<br />
<br />
= Spoke Node =<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management <br><br />
bond0.101 = LAN<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
bond0.620 = WiFi Transit Zone for Internet Access Only (no access to the DMVPN network)<br><br />
bond0.701 = Internet Access Only (no access to the DMVPN network)<br><br />
bond0.1101 = Voice <br><br />
<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.101'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.101? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.101 configuration for bond0.620, bond0.701, bond0.1101, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Networking ==<br />
Update the networking configuration.<br />
<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add interfaces:<br />
<br />
{{cat|/etc/network/interfaces|<br />
...<br />
<br />
auto bond0.8<br />
iface bond0.8 inet static<br />
address 10.1.0.1<br />
netmask 255.255.255.0<br />
<br />
auto bond0.64<br />
iface bond0.64 inet static<br />
address <%DMVPN_DMZ_ADDRESS%><br />
netmask <%DMVPN_DMZ_NETMASK%><br />
<br />
auto bond0.620<br />
iface bond0.620 inet static<br />
address <%DMVPN_WIFI_TRANSIT_IP_ADDRESS%><br />
netmask <%WIFI_TRANSIT_NETMASK%><br />
<br />
...<br />
<br />
auto bond0.256<br />
iface bond0.256 inet static<br />
address <%ISP1_IP_ADDRESS%><br />
netmask <%ISP1_NETMASK%><br />
<br />
auto bond0.257<br />
iface bond0.257 inet static<br />
address <%ISP2_IP_ADDRESS%><br />
netmask <%ISP2_NETMASK%><br />
}}<br />
<br />
== Bonding ==<br />
Update the bonding configuration.<br />
<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add <code>bond-mode</code>, <code>bond-miimon</code> and <code>bond-updelay</code> parameters to the <code>bond0</code> stanza:<br />
<br />
{{cat|/etc/network/interfaces|<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
...<br />
}}<br />
<br />
Bring up the new bonding settings:<br />
<br />
{{Cmd|ifdown bond0<br />
ifup bond0}}<br />
<br />
<br />
== Physically install ==<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to <code>eth0</code>. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== SSH ==<br />
Remove password authentication and DNS reverse lookup:<br />
<br />
{{Cmd|sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Restart ssh:<br />
{{Cmd|/etc/init.d/sshd restart}}<br />
<br />
== NTP server ==<br />
In order to have attached devices syncing their time agains this host, we need to do some modifications to chrony config.<BR><br />
Add '<code>allow all</code>' to the end of the '<code>/etc/chrony/chrony.conf</code>' so the file looks something like this:<br />
<br />
{{cat|/etc/chrony/chrony.conf|<br />
server pool.ntp.org <br />
initstepslew 10 pool.ntp.org<br />
commandkey 10<br />
keyfile /etc/chrony/chrony.keys<br />
driftfile /etc/chrony/chrony.drift<br />
allow all<br />
}}<br />
<br />
Restart chronyd for the changes to take effect<br />
{{cmd|/etc/init.d/chronyd restart}}<br />
<br />
== Recursive DNS ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add -U unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<br />
{{cat|/etc/unbound/unbound.conf|<br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
}}<br />
<br />
Start unbound and start using unbound on this host:<br />
<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
{{cat|/etc/network/interfaces|<nowiki><br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
</nowiki>}}<br />
<br />
Bring up the new <code>gre1</code> interface:<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor create <code>/etc/ipsec.conf</code> and set the content to the following:<br />
<br />
{{cat|/etc/ipsec.conf|<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
}}<br />
<br />
Create missing directory:<br />
<br />
{{Cmd|mkdir /etc/racoon/}}<br />
<br />
Extract your pfx into <code>/etc/racoon</code>, using the filenames '''<code>ca.pem</code>''', '''<code>cert.pem</code>''', and '''<code>key.pem</code>''' (see [[Dynamic_Multipoint_VPN_%28DMVPN%29#Extract_Certificates|instructions above]] for command).<br />
<br />
With your favorite editor create <code>/etc/racoon/racoon.conf</code> and set the content to the following:<br />
<br />
{{cat|/etc/racoon/racoon.conf|<br />
path certificate "/etc/racoon/";<br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
}}<br />
<br />
Edit <code>/etc/conf.d/racoon</code> and unset <code>RACOON_PSK_FILE</code>:<br />
<br />
{{cat|/etc/conf.d/racoon|<br />
...<br />
RACOON_PSK_FILE{{=}}<br />
...<br />
}}<br />
<br />
Start service(s):<br />
<br />
{{Cmd|/etc/init.d/racoon start<br />
rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
{{cat|/etc/opennhrp/opennhrp.conf|<br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
<br />
interface bond0.620<br />
shortcut-destination<br />
}}<br />
<br />
You must have a DNS A record ''<code>hub.example.com</code>'' for each hub node IP address.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
{{cat|/etc/opennhrp/opennhrp-script|<nowiki>#!/bin/sh<br />
<br />
MYAS=$(sed -n 's/router bgp \(\d*\)/\1/p' < /etc/quagga/bgpd.conf)<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</nowiki>}}<br />
<br />
Make it executable and start service(s):<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script<br />
/etc/init.d/opennhrp start<br />
rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add quagga<br />
touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following (replace <code>strongpassword</code> with a password of your choice and <code>%HUB_GRE_IP%</code> with the '''Hub''' node GRE IP address):<br />
* Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
{{cat|/etc/quagga/bgpd.conf|<br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
}}<br />
<br />
Start service(s):<br />
<br />
{{Cmd|/etc/init.d/bgpd start<br />
rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
Install package(s):<br />
<br />
{{Cmd|echo tun >> /etc/modules<br />
modprobe tun<br />
apk add openvpn openssl<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024}}<br />
<br />
Configure openvpn:<br />
<br />
{{cat|/etc/openvpn/openvpn.conf|<br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
}}<br />
<br />
Start service(s):<br />
<br />
{{Cmd|/etc/init.d/openvpn start<br />
rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add awall}}<br />
<br />
Enable IP forwarding:<br />
<br />
{{Cmd|sysctl -w net.ipv4.ip_forward{{=}}1<br />
sed -i 's/.*net\.ipv4\.ip_forward.*$/net.ipv4.ip_forward {{=}} 1/g' /etc/sysctl.conf}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
{{cat|/etc/awall/optional/params.json|<br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF": "bond0.8",<br />
"C_IF": "bond0.64",<br />
"DE_IF": "bond0.620",<br />
"ISP1_IF": "bond0.256",<br />
"ISP2_IF": "bond0.257"<br />
}<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/internet-host.json|<br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/openvpn.json|<br />
{<br />
"description": "OpenVPN support",<br />
<br />
"import": "internet-host",<br />
<br />
"service": { <br />
"openvpn": { "proto": "udp", "port": 1194 }<br />
},<br />
<br />
"filter": [ <br />
{ "in": "E", "out": "_fw", "service": "openvpn", "action": "accept" }<br />
]<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/clampmss.json|<br />
{<br />
"description": "Deal with ISPs afraid of ICMP",<br />
<br />
"import": "internet-host",<br />
<br />
"clamp-mss": [ { "out": "E" } ]<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/mark.json|<br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/dmvpn.json|<br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
}}<br />
<br />
{{cat|/etc/awall/optional/vpnc.json|<br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" },<br />
"DE": { "iface": "$DE_IF" }<br />
<br />
},<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "DE", "out": "E", "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"out": "DE",<br />
"service": [ "ssh", "http", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
}}<br />
<br />
Activate the firewall:<br />
<br />
{{Cmd|modprobe ip_tables<br />
modprobe iptable_nat <br />
awall enable clampmss<br />
awall enable openvpn<br />
awall enable vpnc<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add pingu<br />
echo -e "1\tisp1">> /etc/iproute2/rt_tables<br />
echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
Configure pingu to monitor our <code>bond0.256</code> and <code>bond0.257</code> interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<br />
{{cat|/etc/pingu/pingu.conf|<br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
fwmark 1<br />
rule-priority 20000<br />
# google dns<br />
ping 8.8.8.8<br />
# opendns<br />
ping 208.67.222.222<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
fwmark 2<br />
rule-priority 20000<br />
}<br />
}}<br />
<br />
Make sure we can reach the public IP from our LAN by adding static route rules for our private net(s). Edit <code>/etc/pingu/route-rules</code>:<br />
<br />
{{cat|/etc/pingu/route-rules|<br />
to 10.0.0.0/8 table main prio 1000<br />
to 172.16.0.0/12 table main prio 1000<br />
}}<br />
<br />
Start service(s):<br />
<br />
{{Cmd|/etc/init.d/pingu start<br />
rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via <code>bond0.256</code> so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
Commit configuration:<br />
<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
We will document only what changes from the Spoke node setup.<br />
<br />
== Routing Tables ==<br />
{{Todo|Would we need to change this command - or add some description on why it's documented?}}<br />
<br />
{{Cmd|echo -e "42\tnhrp_shortcut\n43\tnhrp_mtu\n44\tquagga\n}}<br />
<br />
== NHRP ==<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> on Hub 2 and set the content as follows:<br />
<br />
{{cat|/etc/opennhrp/opennhrp.conf|<br />
interface gre1<br />
map %Hub1_GRE_IP%/%MaskBit% hub1.example.org<br />
route-table 44<br />
shortcut<br />
redirect<br />
non-caching<br />
}}<br />
<br />
Do the same on Hub 1 adding the data relative to Hub 2.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and set the content as follows:<br />
<br />
<pre><br />
#!/bin/sh<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -t opennhrp-script -p auth.err "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
logger -t opennhrp-script -p auth.info "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA authenticated"<br />
<br />
(<br />
flock -x 200<br />
<br />
AS=`echo "$CERT" | grep "^AS=" | cut -b 4-`<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "router bgp 65000" \<br />
-c "neighbor $NHRP_DESTADDR remote-as $AS" \<br />
-c "neighbor $NHRP_DESTADDR peer-group leaf" \<br />
-c "neighbor $NHRP_DESTADDR prefix-list net-$AS-in in"<br />
<br />
SEQ=5<br />
(echo "$CERT" | grep "^NET=" | cut -b 5-) | while read NET; do<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "ip prefix-list net-$AS-in seq $SEQ permit $NET le 26"<br />
SEQ=$(($SEQ+5))<br />
done<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
peer-up)<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -p daemon.err "GRE mapping of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU table nhrp_mtu<br />
fi<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42 table nhrp_mtu<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</pre><br />
<br />
== BGP ==<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> on Hub 2 and set the content as follows:<br />
<br />
{{cat|/etc/quagga/bgpd.conf|<br />
password zebra<br />
enable password zebra<br />
log syslog<br />
<br />
router bgp 65000<br />
bgp router-id %Hub2_GRE_IP%<br />
bgp deterministic-med<br />
network %GRE_NETWORK%/%MASK_BITS%<br />
neighbor hub peer-group<br />
neighbor hub next-hop-self<br />
neighbor hub route-map CORE-IN in<br />
neighbor spoke peer-group<br />
neighbor spoke passive<br />
neighbor spoke next-hop-self<br />
neighbor %Spoke1_GRE_IP% remote-as 65001<br />
neighbor %Spoke1_GRE_IP% peer-group spoke<br />
neighbor %Spoke1_GRE_IP% prefix-list net-65001-in in<br />
...<br />
...<br />
...<br />
<br />
neighbor hub remote-as 65000<br />
neighbor %Hub1_GRE_IP% peer-group core<br />
<br />
ip prefix-list net-65001-in seq 5 permit 10.1.0.0/16 le 26<br />
...<br />
<br />
route-map CORE-IN permit 10<br />
set metric +100<br />
}}<br />
<br />
Add the lines <code>neighbor %Spoke1_GRE_IP%...</code> for each spoke node you have. Do the same on Hub 1, changing the relevant data for Hub 2.<br />
<br />
= Troubleshooting the DMVPN =<br />
== Broken [http://en.wikipedia.org/wiki/Path_MTU_Discovery Path MTU Discovery (PMTUD)] ==<br />
ISPs afraid of ICMP (which is somehow legitimate) often just blindly add <code>no ip unreachables</code> in their router interfaces, effectively creating a [http://en.wikipedia.org/wiki/Black_hole_%28networking%29 blackhole router] that breaks PMTUD, since ICMP Type 3 Code 4 packets (Fragmentation Needed) are dropped. PMTUD is needed by ISAKMP that runs on UDP (TCP works because it uses CLAMPMSS).<br />
<br />
For technical details see http://packetlife.net/blog/2008/oct/9/disabling-unreachables-breaks-pmtud/<br />
<br />
PMTUD could also be broken due to badly configured DSL modem/routers or bugged firmware. Turning off the firewall on modem itself or any VPN passthrough functionality it may help.<br />
<br />
You can easily detect which host is the blackhole router by pinging with DF bit set and with packets of standard MTU size, each hop given in your traceroute to destination:<br />
<br />
{{Cmd|ping -M do -s 1472 %IP%}}<br />
{{Note|"-M do" requires GNU ping, present in <code>iputils</code> package}}<br />
<br />
If you don't get a response back (either Echo-Response or Fragmentation-Needed) there's firewall dropping ICMP packets. If it answers to normal ping packets (DF bit cleared), most likely you have hit a blackhole router.<br />
<br />
== Kernel and NHRP Routing Cache Issues ==<br />
{{Todo|...}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=10091
Dynamic Multipoint VPN (DMVPN)
2014-07-20T19:48:11Z
<p>Jbilyk: link to small office services</p>
<hr />
<div>http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, firewall, etc.). [[Small Office Services]] offers additional services such as DHCP for clients, http proxying, and a basic SIP telephone system.<br />
<br />
= Terminology =<br />
;NBMA: ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
;Hub: the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
;Spoke: the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Hardware =<br />
If you are looking for hundreds of megabits of throughput for your VPN with a limited budget, you should consider using [http://www.via.com.tw/en/initiatives/padlock/hardware.jsp VIA Padlock] engine present in VIA processor C7, Eden, Nano and Quad. If you need gigabits throughput you should go instead for an Intel Xeon processor with [http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-instructions-aes-ni AES-NI] and [http://software.intel.com/en-us/articles/intel-sha-extensions SHA Extensions]<br />
<br />
For supporting VIA Padlock engine enable its modules:<br />
<br />
{{Cmd|echo -e "padlock_aes\npadlock-sha" >> /etc/modules}}<br />
<br />
= Extract Certificates =<br />
We will use certificates for DMVPN and for OpenVPN (RoadWarrior clients). If you are in need to generate your own certificates, please see [[Generating_SSL_certs_with_ACF]]. You should use a separate machine for this purpose. If you downloaded the certificates on a Windows machine, you may use [http://winscp.net/eng/download.php WinSCP] to copy them on the DMVPN box.<br />
<br />
Here are the general purpose instruction for extracting certificates from pfx files:<br />
<br />
{{Cmd|openssl pkcs12 -in cert.pfx -cacerts -nokeys -out cacert.pem<br />
openssl pkcs12 -in cert.pfx -nocerts -nodes -out serverkey.pem<br />
openssl pkcs12 -in cert.pfx -nokeys -clcerts -out cert.pem<br />
}}<br />
<br />
Set appropriate permission for your certificate files:<br />
<br />
{{Cmd|chmod 600 *.pem *.pfx}}<br />
<br />
= Spoke Node =<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.620 = WiFi Transit Zone for Internet Access Only (no access to the DMVPN network)<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.620, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Networking ==<br />
Update the networking configuration.<br />
<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add interfaces:<br />
<br />
{{cat|/etc/network/interfaces|<br />
...<br />
<br />
auto bond0.8<br />
iface bond0.8 inet static<br />
address 10.1.0.1<br />
netmask 255.255.255.0<br />
<br />
auto bond0.64<br />
iface bond0.64 inet static<br />
address <%DMVPN_DMZ_ADDRESS%><br />
netmask <%DMVPN_DMZ_NETMASK%><br />
<br />
auto bond0.620<br />
iface bond0.620 inet static<br />
address <%DMVPN_WIFI_TRANSIT_IP_ADDRESS%><br />
netmask <%WIFI_TRANSIT_NETMASK%><br />
<br />
...<br />
<br />
auto bond0.256<br />
iface bond0.256 inet static<br />
address <%ISP1_IP_ADDRESS%><br />
netmask <%ISP1_NETMASK%><br />
<br />
auto bond0.257<br />
iface bond0.257 inet static<br />
address <%ISP2_IP_ADDRESS%><br />
netmask <%ISP2_NETMASK%><br />
}}<br />
<br />
== Bonding ==<br />
Update the bonding configuration.<br />
<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add <code>bond-mode</code>, <code>bond-miimon</code> and <code>bond-updelay</code> parameters to the <code>bond0</code> stanza:<br />
<br />
{{cat|/etc/network/interfaces|<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
...<br />
}}<br />
<br />
Bring up the new bonding settings:<br />
<br />
{{Cmd|ifdown bond0<br />
ifup bond0}}<br />
<br />
<br />
== Physically install ==<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to <code>eth0</code>. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== SSH ==<br />
Remove password authentication and DNS reverse lookup:<br />
<br />
{{Cmd|sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Restart ssh:<br />
{{Cmd|/etc/init.d/sshd restart}}<br />
<br />
== NTP server ==<br />
In order to have attached devices syncing their time agains this host, we need to do some modifications to chrony config.<BR><br />
Add '<code>allow all</code>' to the end of the '<code>/etc/chrony/chrony.conf</code>' so the file looks something like this:<br />
<br />
{{cat|/etc/chrony/chrony.conf|<br />
server pool.ntp.org <br />
initstepslew 10 pool.ntp.org<br />
commandkey 10<br />
keyfile /etc/chrony/chrony.keys<br />
driftfile /etc/chrony/chrony.drift<br />
allow all<br />
}}<br />
<br />
Restart chronyd for the changes to take effect<br />
{{cmd|/etc/init.d/chronyd restart}}<br />
<br />
== Recursive DNS ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add -U unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<br />
{{cat|/etc/unbound/unbound.conf|<br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
}}<br />
<br />
Start unbound and start using unbound on this host:<br />
<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
{{cat|/etc/network/interfaces|<nowiki><br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
</nowiki>}}<br />
<br />
Bring up the new <code>gre1</code> interface:<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor create <code>/etc/ipsec.conf</code> and set the content to the following:<br />
<br />
{{cat|/etc/ipsec.conf|<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
}}<br />
<br />
Create missing directory:<br />
<br />
{{Cmd|mkdir /etc/racoon/}}<br />
<br />
Extract your pfx into <code>/etc/racoon</code>, using the filenames '''<code>ca.pem</code>''', '''<code>cert.pem</code>''', and '''<code>key.pem</code>''' (see [[Dynamic_Multipoint_VPN_%28DMVPN%29#Extract_Certificates|instructions above]] for command).<br />
<br />
With your favorite editor create <code>/etc/racoon/racoon.conf</code> and set the content to the following:<br />
<br />
{{cat|/etc/racoon/racoon.conf|<br />
path certificate "/etc/racoon/";<br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
}}<br />
<br />
Edit <code>/etc/conf.d/racoon</code> and unset <code>RACOON_PSK_FILE</code>:<br />
<br />
{{cat|/etc/conf.d/racoon|<br />
...<br />
RACOON_PSK_FILE{{=}}<br />
...<br />
}}<br />
<br />
Start service(s):<br />
<br />
{{Cmd|/etc/init.d/racoon start<br />
rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
{{cat|/etc/opennhrp/opennhrp.conf|<br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
<br />
interface bond0.620<br />
shortcut-destination<br />
}}<br />
<br />
You must have a DNS A record ''<code>hub.example.com</code>'' for each hub node IP address.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
{{cat|/etc/opennhrp/opennhrp-script|<nowiki>#!/bin/sh<br />
<br />
MYAS=$(sed -n 's/router bgp \(\d*\)/\1/p' < /etc/quagga/bgpd.conf)<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</nowiki>}}<br />
<br />
Make it executable and start service(s):<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script<br />
/etc/init.d/opennhrp start<br />
rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add quagga<br />
touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following (replace <code>strongpassword</code> with a password of your choice and <code>%HUB_GRE_IP%</code> with the '''Hub''' node GRE IP address):<br />
* Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
{{cat|/etc/quagga/bgpd.conf|<br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
}}<br />
<br />
Start service(s):<br />
<br />
{{Cmd|/etc/init.d/bgpd start<br />
rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
Install package(s):<br />
<br />
{{Cmd|echo tun >> /etc/modules<br />
modprobe tun<br />
apk add openvpn openssl<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024}}<br />
<br />
Configure openvpn:<br />
<br />
{{cat|/etc/openvpn/openvpn.conf|<br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
}}<br />
<br />
Start service(s):<br />
<br />
{{Cmd|/etc/init.d/openvpn start<br />
rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add awall}}<br />
<br />
Enable IP forwarding:<br />
<br />
{{Cmd|sysctl -w net.ipv4.ip_forward{{=}}1<br />
sed -i 's/.*net\.ipv4\.ip_forward.*$/net.ipv4.ip_forward {{=}} 1/g' /etc/sysctl.conf}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
{{cat|/etc/awall/optional/params.json|<br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF": "bond0.8",<br />
"C_IF": "bond0.64",<br />
"DE_IF": "bond0.620",<br />
"ISP1_IF": "bond0.256",<br />
"ISP2_IF": "bond0.257"<br />
}<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/internet-host.json|<br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/openvpn.json|<br />
{<br />
"description": "OpenVPN support",<br />
<br />
"import": "internet-host",<br />
<br />
"service": { <br />
"openvpn": { "proto": "udp", "port": 1194 }<br />
},<br />
<br />
"filter": [ <br />
{ "in": "E", "out": "_fw", "service": "openvpn", "action": "accept" }<br />
]<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/clampmss.json|<br />
{<br />
"description": "Deal with ISPs afraid of ICMP",<br />
<br />
"import": "internet-host",<br />
<br />
"clamp-mss": [ { "out": "E" } ]<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/mark.json|<br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
}}<br />
<br />
<br />
<br />
{{cat|/etc/awall/optional/dmvpn.json|<br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
}}<br />
<br />
{{cat|/etc/awall/optional/vpnc.json|<br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" },<br />
"DE": { "iface": "$DE_IF" }<br />
<br />
},<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "DE", "out": "E", "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"out": "DE",<br />
"service": [ "ssh", "http", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
}}<br />
<br />
Activate the firewall:<br />
<br />
{{Cmd|modprobe ip_tables<br />
modprobe iptable_nat <br />
awall enable clampmss<br />
awall enable openvpn<br />
awall enable vpnc<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
Install package(s):<br />
<br />
{{Cmd|apk add pingu<br />
echo -e "1\tisp1">> /etc/iproute2/rt_tables<br />
echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
Configure pingu to monitor our <code>bond0.256</code> and <code>bond0.257</code> interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<br />
{{cat|/etc/pingu/pingu.conf|<br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
fwmark 1<br />
rule-priority 20000<br />
# google dns<br />
ping 8.8.8.8<br />
# opendns<br />
ping 208.67.222.222<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
fwmark 2<br />
rule-priority 20000<br />
}<br />
}}<br />
<br />
Make sure we can reach the public IP from our LAN by adding static route rules for our private net(s). Edit <code>/etc/pingu/route-rules</code>:<br />
<br />
{{cat|/etc/pingu/route-rules|<br />
to 10.0.0.0/8 table main prio 1000<br />
to 172.16.0.0/12 table main prio 1000<br />
}}<br />
<br />
Start service(s):<br />
<br />
{{Cmd|/etc/init.d/pingu start<br />
rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via <code>bond0.256</code> so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
Commit configuration:<br />
<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
We will document only what changes from the Spoke node setup.<br />
<br />
== Routing Tables ==<br />
{{Todo|Would we need to change this command - or add some description on why it's documented?}}<br />
<br />
{{Cmd|echo -e "42\tnhrp_shortcut\n43\tnhrp_mtu\n44\tquagga\n}}<br />
<br />
== NHRP ==<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> on Hub 2 and set the content as follows:<br />
<br />
{{cat|/etc/opennhrp/opennhrp.conf|<br />
interface gre1<br />
map %Hub1_GRE_IP%/%MaskBit% hub1.example.org<br />
route-table 44<br />
shortcut<br />
redirect<br />
non-caching<br />
}}<br />
<br />
Do the same on Hub 1 adding the data relative to Hub 2.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and set the content as follows:<br />
<br />
<pre><br />
#!/bin/sh<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -t opennhrp-script -p auth.err "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
logger -t opennhrp-script -p auth.info "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA authenticated"<br />
<br />
(<br />
flock -x 200<br />
<br />
AS=`echo "$CERT" | grep "^AS=" | cut -b 4-`<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "router bgp 65000" \<br />
-c "neighbor $NHRP_DESTADDR remote-as $AS" \<br />
-c "neighbor $NHRP_DESTADDR peer-group leaf" \<br />
-c "neighbor $NHRP_DESTADDR prefix-list net-$AS-in in"<br />
<br />
SEQ=5<br />
(echo "$CERT" | grep "^NET=" | cut -b 5-) | while read NET; do<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "ip prefix-list net-$AS-in seq $SEQ permit $NET le 26"<br />
SEQ=$(($SEQ+5))<br />
done<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
peer-up)<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -p daemon.err "GRE mapping of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU table nhrp_mtu<br />
fi<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42 table nhrp_mtu<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</pre><br />
<br />
== BGP ==<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> on Hub 2 and set the content as follows:<br />
<br />
{{cat|/etc/quagga/bgpd.conf|<br />
password zebra<br />
enable password zebra<br />
log syslog<br />
<br />
router bgp 65000<br />
bgp router-id %Hub2_GRE_IP%<br />
bgp deterministic-med<br />
network %GRE_NETWORK%/%MASK_BITS%<br />
neighbor hub peer-group<br />
neighbor hub next-hop-self<br />
neighbor hub route-map CORE-IN in<br />
neighbor spoke peer-group<br />
neighbor spoke passive<br />
neighbor spoke next-hop-self<br />
neighbor %Spoke1_GRE_IP% remote-as 65001<br />
neighbor %Spoke1_GRE_IP% peer-group spoke<br />
neighbor %Spoke1_GRE_IP% prefix-list net-65001-in in<br />
...<br />
...<br />
...<br />
<br />
neighbor hub remote-as 65000<br />
neighbor %Hub1_GRE_IP% peer-group core<br />
<br />
ip prefix-list net-65001-in seq 5 permit 10.1.0.0/16 le 26<br />
...<br />
<br />
route-map CORE-IN permit 10<br />
set metric +100<br />
}}<br />
<br />
Add the lines <code>neighbor %Spoke1_GRE_IP%...</code> for each spoke node you have. Do the same on Hub 1, changing the relevant data for Hub 2.<br />
<br />
= Troubleshooting the DMVPN =<br />
== Broken [http://en.wikipedia.org/wiki/Path_MTU_Discovery Path MTU Discovery (PMTUD)] ==<br />
ISPs afraid of ICMP (which is somehow legitimate) often just blindly add <code>no ip unreachables</code> in their router interfaces, effectively creating a [http://en.wikipedia.org/wiki/Black_hole_%28networking%29 blackhole router] that breaks PMTUD, since ICMP Type 3 Code 4 packets (Fragmentation Needed) are dropped. PMTUD is needed by ISAKMP that runs on UDP (TCP works because it uses CLAMPMSS).<br />
<br />
For technical details see http://packetlife.net/blog/2008/oct/9/disabling-unreachables-breaks-pmtud/<br />
<br />
PMTUD could also be broken due to badly configured DSL modem/routers or bugged firmware. Turning off the firewall on modem itself or any VPN passthrough functionality it may help.<br />
<br />
You can easily detect which host is the blackhole router by pinging with DF bit set and with packets of standard MTU size, each hop given in your traceroute to destination:<br />
<br />
{{Cmd|ping -M do -s 1472 %IP%}}<br />
{{Note|"-M do" requires GNU ping, present in <code>iputils</code> package}}<br />
<br />
If you don't get a response back (either Echo-Response or Fragmentation-Needed) there's firewall dropping ICMP packets. If it answers to normal ping packets (DF bit cleared), most likely you have hit a blackhole router.<br />
<br />
== Kernel and NHRP Routing Cache Issues ==<br />
{{Todo|...}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10090
Small Office Services
2014-07-20T19:44:43Z
<p>Jbilyk: add in features</p>
<hr />
<div><br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the [[Dynamic Multipoint VPN (DMVPN)|DMVPN]] spoke node.<br />
<br />
The following services will be available in addition to the encrypted communications between offices provided by the DMVPN network:<br />
* Internet browsing proxy server with domain filtering (wired clients on protected internal network)<br />
* Separate proxy for wifi clients<br />
* SIP phone system including web based provisioning and basic voicemail services<br />
<br />
{{Tip|At the time of writing, the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WEB_PROXY_IP_ADDRESS%><br />
netmask <%DMVPN_LAN_NETMASK%><br />
gateway <%DMVPN_LAN_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$WEB_PROXY",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth_3<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth_701<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth_1101<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Voice VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address <%DHCPDNS_VOICE_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
up ip address add <%DHCPDNS_VOIP_IP_ADDRESS2%>/25 dev eth0<br />
#Management VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address <%MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
<br />
<br />
#WiFi VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address <%DHCPDNS_WIFI_IP_ADDRESS%><br />
netmask <%WIFI_NETMASK%><br />
<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers <%DMVPN_VOICE_IP_ADDRESS%>;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet <%VOICE_SUBNET%> netmask <%VOICE_NETMASK%><br />
{<br />
range <%VOICE_DHCP_RANGE%>;<br />
option domain-name-servers <%DHCPDNS_VOICE_IP_ADDRESS%>;<br />
option routers <%DMVPN_VOICE_IP_ADDRESS%>;<br />
option boot-server "http://<%SIP_IP_ADDRESS%>";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet <%WIFI_SUBNET%> netmask <%WIFI_NETMASK%><br />
{<br />
range <%WIFI_DHCP_RANGE%>;<br />
option routers <%WIFI_PROXY_IP_ADDRESS%>;<br />
option domain-name-servers <%DHCPDNS_WIFI_IP_ADDRESS%>; <br />
option domain-name "<%WIFI_DOMAIN%>";<br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: <%DHCPDNS_VOICE_IP_ADDRESS%><br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: <%DHCPDNS_VOICE_IP_ADDRESS2%><br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver <%DHCPDNS_VOICE_IP_ADDRESS%> > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: <%DHCPDNS_VOICE_IP_ADDRESS2%><br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A <%DHCPDNS_VOICE_IP_ADDRESS%><br />
<br />
;A Records for SIP Devices<br />
sip IN A <%SIP_IP_ADDRESS%><br />
map IN A <%VMAIL_IP_ADDRESS%><br />
<br />
;NAPTR Records<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.vmail.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp IN SRV 10 1 5060 sip<br />
_sip._udp IN SRV 10 1 5060 vmail<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%SIP_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'listen_addresses', and the 'log_destination' variables to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
listen_addresses {{=}}'<%SIP_IP_ADDRESS%><br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the B2BUA container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n b2bua -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.b2bua}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/b2bua/config, to reflect the network for the B2BUA container<br />
<br />
{{cat|/var/lib/lxc/b2bua/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.b2bua}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.b2bua}}<br />
<br />
== Enter the B2BUA container ==<br />
{{Cmd|lxc-console -n b2bua}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%B2BUA_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
<?xml version="1.0"?><br />
<document type="freeswitch/xml"><br />
<br />
<!-- Variables we need to set --><br />
<br />
<X-PRE-PROCESS cmd="set" data="b2bua=<%B2BUA_IP_ADDRESS%>"/><br />
<X-PRE-PROCESS cmd="set" data="domain=office.example.net"/><br />
<X-PRE-PROCESS cmd="set" data="siprouter=office.example.net"/><br />
<br />
<!-- Variables we don´t need to set --><br />
<br />
<!-- External SIP Profile --><br />
<X-PRE-PROCESS cmd="set" data="external_sip_port=5060"/><br />
<!-- Glogal codecs --><br />
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=G7221@32000h,G7221@16000h,G722,PCMU,PCMA,GSM"/><br />
<!-- Outbound codecs --><br />
<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=PCMU,PCMA,GSM"/><br />
<br />
<section name="configuration" description="Various Configuration"><br />
<br />
<configuration name="modules.conf" description="Modules"><br />
<modules><br />
<load module="mod_commands"/><br />
<load module="mod_console"/><br />
<load module="mod_dptools"/><br />
<load module="mod_dialplan_xml"/><br />
<load module="mod_event_socket"/><br />
<load module="mod_logfile"/><br />
<load module="mod_sofia"/><br />
</modules><br />
</configuration><br />
<br />
<configuration name="console.conf" description="Console Logger"><br />
<mappings><br />
<map name="all" value="console,debug,info,notice,warning,err,crit,alert"/><br />
</mappings><br />
<settings><br />
<param name="loglevel" value="info"/><br />
</settings><br />
</configuration><br />
<br />
<configuration name="logfile.conf" description="File Logging"><br />
<settings><br />
<param name="rotate-on-hup" value="true"/><br />
</settings><br />
<profiles><br />
<profile name="default"><br />
<settings><br />
<param name="rollover" value="10485760"/><br />
</settings><br />
<mappings><br />
<map name="all" value="debug,info,notice,warning,err,crit,alert"/><br />
</mappings><br />
</profile><br />
</profiles><br />
</configuration><br />
<br />
<configuration name="sofia.conf" description="sofia Endpoint"><br />
<global_settings><br />
<param name="log-level" value="0"/><br />
<param name="debug-presence" value="0"/><br />
<param name="debug" value="0"/><br />
<param name="sip-trace" value="no"/><br />
<param name="log-auth-failures" value="false"/><br />
<param name="forward-unsolicited-mwi-notify" value="false"/><br />
<param name="rfc2833-pt" value="101"/><br />
<param name="sip-port" value="5060"/><br />
<param name="dialplan" value="XML"/><br />
<param name="dtmf-duration" value="2000"/><br />
<param name="rtp-timer-name" value="soft"/><br />
<param name="inbound-codec-negotiation" value="generous"/><br />
<param name="tls" value="false"/><br />
<param name="nonce-ttl" value="60"/><br />
<param name="auth-calls" value="false"/><br />
<param name="auth-all-packets" value="false"/><br />
<param name="rtp-timeout-sec" value="300"/><br />
<param name="rtp-hold-timeout-sec" value="1800"/><br />
<param name="challenge-realm" value="auto_from"/><br />
</global_settings><br />
<br />
<profiles><br />
<profile name="$${domain}"><br />
<domains><br />
<domain name="all" alias="false" parse="true"/><br />
</domains><br />
<settings><br />
<param name="debug" value="0"/><br />
<param name="sip-trace" value="no"/><br />
<param name="rfc2833-pt" value="101"/><br />
<param name="sip-port" value="$${external_sip_port}"/><br />
<param name="dialplan" value="XML"/><br />
<param name="context" value="default"/><br />
<param name="dtmf-duration" value="2000"/><br />
<param name="inbound-codec-prefs" value="$${global_codec_prefs}"/><br />
<param name="outbound-codec-prefs" value="$${outbound_codec_prefs}"/><br />
<param name="rtp-timer-name" value="soft"/><br />
<param name="local-network-acl" value="rfc1918.auto"/><br />
<param name="manage-presence" value="false"/><br />
<param name="inbound-codec-negotiation" value="generous"/><br />
<param name="nonce-ttl" value="60"/><br />
<param name="auth-calls" value="false"/><br />
<param name="rtp-ip" value="$${b2bua}"/><br />
<param name="sip-ip" value="$${b2bua}"/><br />
<param name="tls" value="false"/><br />
</settings><br />
</profile> <br />
</profiles> <br />
<br />
</configuration><br />
<br />
<configuration name="switch.conf" description="Core Configuration"><br />
<br />
<cli-keybindings><br />
<key name="1" value="help"/><br />
<key name="2" value="status"/><br />
<key name="3" value="show channels"/><br />
<key name="4" value="show calls"/><br />
<key name="5" value="sofia status"/><br />
<key name="6" value="reloadxml"/><br />
</cli-keybindings><br />
<br />
<settings><br />
<param name="colorize-console" value="true"/><br />
<param name="max-sessions" value="1000"/><br />
<param name="sessions-per-second" value="30"/><br />
<param name="loglevel" value="debug"/><br />
<param name="dump-cores" value="yes"/><br />
<param name="rtp-enable-zrtp" value="false"/><br />
<param name="rtp-start-port" value="13000"/><br />
<param name="rtp-end-port" value="18000"/><br />
</settings><br />
</configuration><br />
<br />
<configuration name="post_load_modules.conf" description="Post-load modules"/><br />
<br />
</section><br />
<br />
<!-- Incomming Calls --><br />
<section name="dialplan" description="Regex/XML Dialplan"><br />
<context name="default"><br />
<extension name="b2b-in"><br />
<condition field="destination_number" expression="^(\d*)$"><br />
<action application="set" data="ringback=%(2000,4000,440.0,480.0)"/><br />
<action application="set" data="hangup_after_bridge=true"/><br />
<action application="set" data="continue_on_fail=true"/><br />
<action application="set" data="ignore_early_media=true"/> <br />
<action application="set" data="bypass_media=true"/> <br />
<action application="answer"/><br />
<action application="sleep" data="1000"/><br />
<action application="unset" data="sip_h_P-ARP"/><br />
<action application="bridge" data="sofia/$${domain}/$1@$${siprouter}"/><br />
</condition><br />
</extension><br />
</context> <br />
</section><br />
</document><br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
= Install the wifi Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WIFI_IP_ADDRESS%><br />
netmask <%VPNc_WIFI_NETMASK%><br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address <%WIFI_TRANSIT_IP_ADDRESS%><br />
netmask <%WIFI_TRANSIT_NETMASK%><br />
gateway <%DMVPN_WIFI_TRANSIT_IP_ADDRESS%><br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address <%WIFI_MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Small_Office_Services&diff=10087
Small Office Services
2014-07-17T02:39:50Z
<p>Jbilyk: clean ups</p>
<hr />
<div>{{Draft}}<br />
'''Abstract''': This document will outline how to provide various network services for a small remote office, using Linux containerization (LXC). It is designed to be a complement to the Dynamic Multipoint VPN (DMVPN) spoke node.<br />
<br />
{{Tip|At the time of writing this document the recommended Alpine version for building the Host box for the containers should be at minimum 2.7.9 64 bit.}}<br />
<br />
= Hardware =<br />
For an office that will serve under 20 people, the following containers can easily run on low-power hardware such as a Via Nano 1.6Ghz Jetway board with 8GB RAM with dual 500GB SATA hard drives running in RAID 1 (software).<br />
<br />
= Setup LXC Host Box =<br />
<br />
== Boot Alpine USB == <br />
Follow the instructions on http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.<br />
<br />
== Alpine Setup ==<br />
{{Cmd|setup-alpine}}<br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''lxc-host'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.3'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.3? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|'''<%LXCHOST_MANAGEMENT_IP_ADDRESS%>'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|'''<%DMVPN_MANAGEMENT_NETMASK%>'''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|'''<%DMVPN_MANAGEMENT_NET_IP%>'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''no'''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''office.example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''http://'''<%DMVPN_LAN_IP%>''':8080''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|'''sda sdb'''<br />
|-<br />
|<code>How would you like to use them? ('sys', 'data' or '?' for help):</code><br />
|'''data'''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
Upgrade packages<br />
{{Cmd|apk update<br />
apk upgrade}}<br />
<br />
Save Changes <br />
{{Cmd|lbu commit}}<br />
<br />
Finish Setup with a reboot<br />
{{Cmd|reboot}}<br />
<br />
== Setup Networking ==<br />
With your favorite editor configure /etc/network/interfaces<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto bond0<br />
iface bond0 inet manual<br />
bond-slaves eth0 eth1<br />
bond-mode balance-tlb<br />
bond-miimon 100<br />
bond-updelay 500<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.3<br />
iface bond0.3 inet static<br />
address <%LXCHOST_MANAGEMENT_IP_ADDRESS%><br />
netmask <%DMVPN_MANAGEMENT_NETMASK%><br />
gateway <%DMVPN_MANAGEMENT_IP%><br />
<br />
auto bond0.101<br />
iface bond0.101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.1101<br />
iface bond0.1101 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
<br />
auto bond0.701<br />
iface bond0.701 inet manual<br />
up ip link set $IFACE up<br />
down ip link set $IFACE down<br />
}}<br />
<br />
Apply changes by restarting networking<br />
{{Cmd|/etc/init.d/networking restart}}<br />
<br />
== Enable IP Forwarding ==<br />
{{Cmd|echo "1" > /proc/sys/net/ipv4/ip_forward}}<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the base policy for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|modprobe ip_tables<br />
awall enable base<br />
awall activate -f<br />
rc-update add iptables}}<br />
<br />
== Install LXC ==<br />
Install the LXC and Bridge packages<br />
{{Cmd|apk add lxc bridge}}<br />
With your favorite editor configure /etc/lxc/default.conf<br />
{{cat|/etc/lxc/default.conf|<br />
## Allow containers in the same VLAN to see each other<br />
lxc.network.type {{=}} macvlan<br />
lxc.network.macvlan.mode {{=}} bridge<br />
lxc.network.link {{=}} bond0.3<br />
lxc.network.name {{=}} eth0<br />
<br />
## Restrict capabilities of the containers<br />
lxc.cap.drop {{=}} sys_admin audit_control audit_write fsetid ipc_lock<br />
lxc.cap.drop {{=}} ipc_owner lease linux_immutable mac_admin mac_override<br />
lxc.cap.drop {{=}} mknod setfcap setpcap sys_module sys_nice sys_pacct<br />
lxc.cap.drop {{=}} sys_ptrace sys_rawio sys_tty_config sys_time<br />
}}<br />
Finish Installation<br />
{{Cmd|lbu ci<br />
reboot}}<br />
= Install the Web Proxy Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n webproxy -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.webproxy}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/webproxy/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/webproxy/config|<br />
...<br />
lxc.network.link {{=}} bond0.101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.webproxy}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.webproxy}}<br />
<br />
== Enter the webproxy container ==<br />
{{Cmd|lxc-console -n webproxy}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WEB_PROXY_IP_ADDRESS%><br />
netmask <%DMVPN_LAN_NETMASK%><br />
gateway <%DMVPN_LAN_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Add rule to DMVPN awall policy to allow this proxy out to the internet<br />
{{Note| this is to be configured on the DMVPN awall config}}<br />
{{cat| /etc/awall/optional/internet-host.json|<br />
{<br />
"in": "B",<br />
"src": "$WEB_PROXY",<br />
"out": "E",<br />
"action": "accept",<br />
},<br />
}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/webproxy.json|<br />
{<br />
"description": "Web Proxy",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "http", "http-alt" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable webproxy<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure the Squid Web Proxy Service ==<br />
Install the required packages <br />
{{Cmd|apk add acf-squid squark acf-lighttpd}}<br />
<br />
Configure /etc/squid/squid.conf, replace <%WEBPROXY_IP_ADDRESS%>, <%HOSTNAME%>, and <%DOMAIN%><br />
{{cat|/etc/init.d/squid/squid.conf|<br />
<pre><br />
#Squid config for webproxy<br />
<br />
# This port listens for client requests<br />
http_port 8080<br />
<br />
visible_hostname <%HOSTNAME%>.<%DOMAIN%><br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Fix for problems with branch file transfer application<br />
# ignore_expect_100 on (deprecated)<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
# <br />
# Authentication<br />
#<br />
<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst <%WEBPROXY_IP_ADDRESS%><br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones <br />
acl Zone_B src <%LAN_SUBNET%>/<%LAN_SLASH_NOTATION%><br />
#acl Zone_D src <%WiFi_SUBNET%>/<%WiFi_SLASH_NOTATION%><br />
<br />
# Settings migrated from smn<br />
acl Zone_B_AllowedUserDomains dstdomain "/etc/squid/alloweduserdomains"<br />
acl Zone_B_AllowedServicesHosts src "/etc/squid/allowedserviceshosts"<br />
acl Zone_B_AllowedServicesDomains dstdomain "/etc/squid/allowedservicesdomains"<br />
<br />
# Settings migrated from services<br />
acl AnonBrowsers browser "/etc/squid/anonbrowserlist"<br />
acl AnonIPAddrs src "/etc/squid/anoniplist"<br />
acl AnonDomain url_regex "/etc/squid/anondomainlist"<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_B and Zone_C to access hosts listed in<br />
# /etc/squid/alloweduserdomains<br />
http_access allow Zone_B Zone_B_AllowedUserDomains<br />
<br />
# Allow hosts listed in /etc/squid/allowedserviceshosts to<br />
# access domains listed in /etc/squid/allowedservicesdomains<br />
http_access allow Zone_B_AllowedServicesHosts Zone_B_AllowedServicesDomains<br />
<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#We do not want authentication for these sites:<br />
url_rewrite_access deny Zone_B Zone_B_AllowedUserDomains<br />
url_rewrite_access deny Zone_B Zone_B_AllowedServicesDomains<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
<br />
Configure /etc/lighttpd/lighttpd.conf, replace <%WEBPROXY_IP_ADDRESS%><br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
##############################################################################<br />
# Default lighttpd.conf for Gentoo.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $<br />
###############################################################################<br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
include "mime-types.conf" <br />
<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
server.follow-symlink = "enable"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("<%WEBPROXY_IP_ADDRESS%>" => "trust")<br />
<br />
</pre><br />
}}<br />
<br />
Configure mod_cgi.conf<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
</pre><br />
}}<br />
<br />
Link the Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
<br />
Create a Squark group<br />
{{Cmd|addgroup squark}}<br />
<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
<br />
Start lighttpd, and configure the service to start on when container is booted<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
<br />
<br />
Start Squid, and configure to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}<br />
<br />
= Install the DHCP and DNS server Container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n dhcpdns -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.dhcpdns}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/dhcpdns/config, to reflect the network for the web proxy container<br />
<br />
{{cat|/var/lib/lxc/dhcpdns/config|<br />
<pre><br />
#Management Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.3<br />
lxc.network.name = eth_3<br />
<br />
#WiFi Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.701<br />
lxc.network.name = eth_701<br />
<br />
#Voice Network Config<br />
lxc.network.type = macvlan<br />
lxc.network.macvlan.mode = bridge<br />
lxc.network.link = bond0.1101<br />
lxc.network.name = eth_1101<br />
</pre><br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.dhcpdns}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.dhcpdns}}<br />
<br />
== Enter the dhcpdns container ==<br />
{{Cmd|lxc-console -n dhcpdns}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
#Voice VLAN<br />
auto eth0<br />
iface eth0 inet static<br />
address <%DHCPDNS_VOICE_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
up ip address add <%DHCPDNS_VOIP_IP_ADDRESS2%>/25 dev eth0<br />
#Management VLAN<br />
auto eth1<br />
iface eth1 inet static<br />
address <%MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
<br />
<br />
#WiFi VLAN<br />
auto eth2<br />
iface eth2 inet static<br />
address <%DHCPDNS_WIFI_IP_ADDRESS%><br />
netmask <%WIFI_NETMASK%><br />
<br />
<br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dhcp.json|<br />
{<br />
"description": "DHCP",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dhcp",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/dns.json|<br />
{<br />
"description": "DNS",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "dns",<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable dhcp<br />
awall enable dns<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure DHCP and DNS services ==<br />
install the dhcpd package<br />
{{Cmd|apk add acf-dhcp}}<br />
Create a new dhcpd.conf file<br />
{{cat|/etc/dhcp/dhcpd.conf|<br />
<pre><br />
## Common settings<br />
default-lease-time 302400;<br />
max-lease-time 604800;<br />
ddns-update-style none;<br />
log-facility local7;<br />
authoritative;<br />
<br />
## Common options<br />
option time-servers <%DMVPN_VOICE_IP_ADDRESS%>;<br />
option boot-server code 66 = string;<br />
<br />
## Voice<br />
subnet <%VOICE_SUBNET%> netmask <%VOICE_NETMASK%><br />
{<br />
range <%VOICE_DHCP_RANGE%>;<br />
option domain-name-servers <%DHCPDNS_VOICE_IP_ADDRESS%>;<br />
option routers <%DMVPN_VOICE_IP_ADDRESS%>;<br />
option boot-server "http://<%SIP_IP_ADDRESS%>";<br />
option domain-name "office.example.net";<br />
}<br />
<br />
## WiFi<br />
subnet <%WIFI_SUBNET%> netmask <%WIFI_NETMASK%><br />
{<br />
range <%WIFI_DHCP_RANGE%>;<br />
option routers <%WIFI_PROXY_IP_ADDRESS%>;<br />
option domain-name-servers <%DHCPDNS_WIFI_IP_ADDRESS%>; <br />
option domain-name "<%WIFI_DOMAIN%>";<br />
}<br />
</pre><br />
}}<br />
Start DHCP service and add to runlevel default <br />
{{Cmd|rc-service dhcpd start <br />
rc-update add dhcpd}}<br />
<br />
Install nsd and unbound packages<br />
{{Cmd|apk add unbound }}<br />
<br />
Remove unbound.conf<br />
{{Cmd|rm /etc/unbound/unbound.conf}}<br />
<br />
Create with your favorite editor a new configuration for unbound<br />
{{cat|/etc/unbound/unbound.conf|<br />
#Recursive DNS configuration<br />
<br />
server:<br />
interface: <%DHCPDNS_VOICE_IP_ADDRESS%><br />
do-not-query-localhost: no<br />
verbosity: 1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
#use the root.hints file to determine where to send DNS queries outside of network<br />
root-hints: "/etc/unbound/root.hints" <br />
<br />
stub-zone:<br />
name: "office.example.net"<br />
stub-addr: <%DHCPDNS_VOICE_IP_ADDRESS2%><br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
}}<br />
Start Unbound and allow the container to use it<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver <%DHCPDNS_VOICE_IP_ADDRESS%> > /etc/resolv.conf<br />
<br />
Install nsd<br />
{{Cmd|apk add nsd}}<br />
Configure nsd configuration<br />
{{cat|/etc/nsd/nsd.conf|<br />
server:<br />
ip-address: <%DHCPDNS_VOICE_IP_ADDRESS2%><br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: office.example.net<br />
zonefile: office.example.net.zone<br />
}}<br />
<br />
Configure Zone file for nsd<br />
{{cat|/etc/nsd/nsd.conf|<br />
$ORIGIN office.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns admin (<br />
2013032200 ; Serial number [yyyymmddnn]<br />
28800 ; Refresh<br />
7200 ; Retry<br />
864000 ; Expire<br />
86400 ; Min TTL<br />
)<br />
<br />
@ NS ns1<br />
; NSA Servers<br />
ns1 IN A <%DHCPDNS_VOICE_IP_ADDRESS%><br />
<br />
;A Records for SIP Devices<br />
sip IN A <%SIP_IP_ADDRESS%><br />
map IN A <%VMAIL_IP_ADDRESS%><br />
<br />
;NAPTR Records<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.sip.office.example.net.<br />
@ IN NAPTR 10 1 "s" "SIP+D2U" "" _sip._udp.vmail.office.example.net.<br />
<br />
;SIP SRV Record<br />
_sip._udp IN SRV 10 1 5060 sip<br />
_sip._udp IN SRV 10 1 5060 vmail<br />
}}<br />
<br />
Check nsd configuration and start service<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
= Install the SIP Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n sip -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.sip}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/sip/config, to reflect the network for the sip container<br />
<br />
{{cat|/var/lib/lxc/sip/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.sip}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.sip}}<br />
<br />
== Enter the sip container ==<br />
{{Cmd|lxc-console -n sip}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%SIP_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip.json|<br />
{<br />
<br />
"description": "Phone System",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept",<br />
}<br />
]<br />
<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/syslog.json|<br />
{<br />
<br />
"description": "Syslog server",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": "syslog",<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Activate the firewall, and allow iptables to startup automatically at boot<br />
{{Cmd|awall enable base<br />
awall enable sip<br />
awall enable syslog<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
==Install and Configure Postgresql==<br />
Install postgresql package<br />
{{Cmd|apk update<br />
apk add acf-postgresql}}<br />
Prepare the database<br />
{{Cmd|/etc/init.d/postgresql setup}}<br />
Configure /var/lib/postgresql/9.3/data/postgresql.conf to set the 'listen_addresses', and the 'log_destination' variables to show:<br />
{{cat|/var/lib/postgresql/9.3/data/postresql.conf|<br />
..<br />
listen_addresses {{=}}'<%SIP_IP_ADDRESS%><br />
..<br />
log_destination {{=}}'syslog'<br />
}}<br />
Start up the database and configure postgresql to start at boot up<br />
{{Cmd|/etc/init.d/postgresql start<br />
rc-update add postgresql}}<br />
== Install Kamailio ==<br />
Follow the instructions found here: http://wiki.alpinelinux.org/wiki/Kamailio to install and configure Kamailio<br />
<br />
=Install the B2BUA container =<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n b2bua -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.b2bua}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/b2bua/config, to reflect the network for the B2BUA container<br />
<br />
{{cat|/var/lib/lxc/b2bua/config|<br />
...<br />
lxc.network.link {{=}} bond0.1101<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/init.d/lxc.b2bua}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.b2bua}}<br />
<br />
== Enter the B2BUA container ==<br />
{{Cmd|lxc-console -n b2bua}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%B2BUA_IP_ADDRESS%><br />
netmask <%VOICE_NETMASK%><br />
gateway <%DMVPN_VOICE_IP_ADDRESS%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
Configure and enable proxy settings<br />
{{Cmd|setup-proxy http://<%WEBPROXY_IP_ADDRESS%>:8080<br />
. /etc/profile.d/proxy.sh}}<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
<br />
With your favorite editor, create the policies for the firewall<br />
{{cat|/etc/awall/optional/base.json|<br />
{<br />
"description": "Management",<br />
<br />
"policy": [<br />
{ "in": "_fw", "action": "accept" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "ssh", "https", "ping" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
}}<br />
{{cat|/etc/awall/optional/sip-track.json|<br />
{<br />
<br />
"description": "Phone system with SIP connection tracking",<br />
<br />
"filter": [<br />
{<br />
"out": "_fw",<br />
"service": [ "sip", "sip-tls" ],<br />
"action": "accept"<br />
}<br />
]<br />
<br />
}<br />
}}<br />
Enable and activate firewall policies, and configure iptables to start at boot<br />
{{Cmd|awall enable base<br />
awall enable sip-track<br />
awall activate -f<br />
rc-update add iptables<br />
}}<br />
<br />
== Install and Configure Freeswitch ==<br />
Install package<br />
{{Cmd|Install Freeswitch Package}}<br />
<br />
Configure /etc/freeswitch/freeswitch.xml<br />
{{cat|/etc/freeswitch/freeswitch.xml|<br />
<pre><br />
<?xml version="1.0"?><br />
<document type="freeswitch/xml"><br />
<br />
<!-- Variables we need to set --><br />
<br />
<X-PRE-PROCESS cmd="set" data="b2bua=<%B2BUA_IP_ADDRESS%>"/><br />
<X-PRE-PROCESS cmd="set" data="domain=office.example.net"/><br />
<X-PRE-PROCESS cmd="set" data="siprouter=office.example.net"/><br />
<br />
<!-- Variables we don´t need to set --><br />
<br />
<!-- External SIP Profile --><br />
<X-PRE-PROCESS cmd="set" data="external_sip_port=5060"/><br />
<!-- Glogal codecs --><br />
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=G7221@32000h,G7221@16000h,G722,PCMU,PCMA,GSM"/><br />
<!-- Outbound codecs --><br />
<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=PCMU,PCMA,GSM"/><br />
<br />
<section name="configuration" description="Various Configuration"><br />
<br />
<configuration name="modules.conf" description="Modules"><br />
<modules><br />
<load module="mod_commands"/><br />
<load module="mod_console"/><br />
<load module="mod_dptools"/><br />
<load module="mod_dialplan_xml"/><br />
<load module="mod_event_socket"/><br />
<load module="mod_logfile"/><br />
<load module="mod_sofia"/><br />
</modules><br />
</configuration><br />
<br />
<configuration name="console.conf" description="Console Logger"><br />
<mappings><br />
<map name="all" value="console,debug,info,notice,warning,err,crit,alert"/><br />
</mappings><br />
<settings><br />
<param name="loglevel" value="info"/><br />
</settings><br />
</configuration><br />
<br />
<configuration name="logfile.conf" description="File Logging"><br />
<settings><br />
<param name="rotate-on-hup" value="true"/><br />
</settings><br />
<profiles><br />
<profile name="default"><br />
<settings><br />
<param name="rollover" value="10485760"/><br />
</settings><br />
<mappings><br />
<map name="all" value="debug,info,notice,warning,err,crit,alert"/><br />
</mappings><br />
</profile><br />
</profiles><br />
</configuration><br />
<br />
<configuration name="sofia.conf" description="sofia Endpoint"><br />
<global_settings><br />
<param name="log-level" value="0"/><br />
<param name="debug-presence" value="0"/><br />
<param name="debug" value="0"/><br />
<param name="sip-trace" value="no"/><br />
<param name="log-auth-failures" value="false"/><br />
<param name="forward-unsolicited-mwi-notify" value="false"/><br />
<param name="rfc2833-pt" value="101"/><br />
<param name="sip-port" value="5060"/><br />
<param name="dialplan" value="XML"/><br />
<param name="dtmf-duration" value="2000"/><br />
<param name="rtp-timer-name" value="soft"/><br />
<param name="inbound-codec-negotiation" value="generous"/><br />
<param name="tls" value="false"/><br />
<param name="nonce-ttl" value="60"/><br />
<param name="auth-calls" value="false"/><br />
<param name="auth-all-packets" value="false"/><br />
<param name="rtp-timeout-sec" value="300"/><br />
<param name="rtp-hold-timeout-sec" value="1800"/><br />
<param name="challenge-realm" value="auto_from"/><br />
</global_settings><br />
<br />
<profiles><br />
<profile name="$${domain}"><br />
<domains><br />
<domain name="all" alias="false" parse="true"/><br />
</domains><br />
<settings><br />
<param name="debug" value="0"/><br />
<param name="sip-trace" value="no"/><br />
<param name="rfc2833-pt" value="101"/><br />
<param name="sip-port" value="$${external_sip_port}"/><br />
<param name="dialplan" value="XML"/><br />
<param name="context" value="default"/><br />
<param name="dtmf-duration" value="2000"/><br />
<param name="inbound-codec-prefs" value="$${global_codec_prefs}"/><br />
<param name="outbound-codec-prefs" value="$${outbound_codec_prefs}"/><br />
<param name="rtp-timer-name" value="soft"/><br />
<param name="local-network-acl" value="rfc1918.auto"/><br />
<param name="manage-presence" value="false"/><br />
<param name="inbound-codec-negotiation" value="generous"/><br />
<param name="nonce-ttl" value="60"/><br />
<param name="auth-calls" value="false"/><br />
<param name="rtp-ip" value="$${b2bua}"/><br />
<param name="sip-ip" value="$${b2bua}"/><br />
<param name="tls" value="false"/><br />
</settings><br />
</profile> <br />
</profiles> <br />
<br />
</configuration><br />
<br />
<configuration name="switch.conf" description="Core Configuration"><br />
<br />
<cli-keybindings><br />
<key name="1" value="help"/><br />
<key name="2" value="status"/><br />
<key name="3" value="show channels"/><br />
<key name="4" value="show calls"/><br />
<key name="5" value="sofia status"/><br />
<key name="6" value="reloadxml"/><br />
</cli-keybindings><br />
<br />
<settings><br />
<param name="colorize-console" value="true"/><br />
<param name="max-sessions" value="1000"/><br />
<param name="sessions-per-second" value="30"/><br />
<param name="loglevel" value="debug"/><br />
<param name="dump-cores" value="yes"/><br />
<param name="rtp-enable-zrtp" value="false"/><br />
<param name="rtp-start-port" value="13000"/><br />
<param name="rtp-end-port" value="18000"/><br />
</settings><br />
</configuration><br />
<br />
<configuration name="post_load_modules.conf" description="Post-load modules"/><br />
<br />
</section><br />
<br />
<!-- Incomming Calls --><br />
<section name="dialplan" description="Regex/XML Dialplan"><br />
<context name="default"><br />
<extension name="b2b-in"><br />
<condition field="destination_number" expression="^(\d*)$"><br />
<action application="set" data="ringback=%(2000,4000,440.0,480.0)"/><br />
<action application="set" data="hangup_after_bridge=true"/><br />
<action application="set" data="continue_on_fail=true"/><br />
<action application="set" data="ignore_early_media=true"/> <br />
<action application="set" data="bypass_media=true"/> <br />
<action application="answer"/><br />
<action application="sleep" data="1000"/><br />
<action application="unset" data="sip_h_P-ARP"/><br />
<action application="bridge" data="sofia/$${domain}/$1@$${siprouter}"/><br />
</condition><br />
</extension><br />
</context> <br />
</section><br />
</document><br />
</pre><br />
}}<br />
Start Freeswitch and configure to start at boot<br />
{{Cmd|/etc/init.d/freeswitch start<br />
rc-update add freeswitch}}<br />
= Install the wifi Container =<br />
<br />
== Create and Configure the container ==<br />
{{Cmd|lxc-create -n wifi -f /etc/lxc/default.conf -t alpine}}<br />
Create the startup Script<br />
{{Cmd|ln -s /etc/init.d/lxc /etc/init.d/lxc.wifi}}<br />
<br />
Edit the container's config file found at /var/lib/lxc/wifi/config, to reflect the network for the wifi container<br />
<br />
{{cat|/var/lib/lxc/wifi/config|<br />
...<br />
lxc.network.link {{=}} bond0.701<br />
...<br />
}}<br />
<br />
Start the container<br />
{{Cmd|/etc/iniit.d/lxc.wifi}}<br />
<br />
Configure the container to automatically start<br />
{{Cmd|rc-update add lxc.wifi}}<br />
<br />
== Enter the wifi container ==<br />
{{Cmd|lxc-console -n wifi}}<br />
Login as root<br />
{{Note|If the need arises to exit the container press {{Key| Ctrl}}+{{Key| a}} + {{Key| q}}}}<br />
Remove obsolete /etc/network/interfaces<br />
{{Cmd|rm /etc/network/interfaces}}<br />
Create and configure the new /etc/network/interfaces as shown below:<br />
{{cat|/etc/network/interfaces|<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet static<br />
address <%WIFI_IP_ADDRESS%><br />
netmask <%VPNc_WIFI_NETMASK%><br />
<br />
auto eth1<br />
iface eth1 inet static<br />
address <%WIFI_TRANSIT_IP_ADDRESS%><br />
netmask <%WIFI_TRANSIT_NETMASK%><br />
gateway <%DMVPN_WIFI_TRANSIT_IP_ADDRESS%><br />
<br />
auto eth2<br />
iface eth2 inet static<br />
address <%WIFI_MANAGEMENT_IP_ADDRESS%><br />
netmask <%MANAGEMENT_NETMASK%><br />
}}<br />
<br />
Startup networking <br />
{{Cmd| /etc/init.d/networking start}}<br />
<br />
<br />
Configure remote administration<br />
{{Cmd|apk update<br />
setup-sshd -c openssh<br />
sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
Start ssh<br />
{{Cmd|/etc/init.d/sshd start}}<br />
<br />
Configure a passwd for the container<br />
{{Cmd|passwd}}<br />
<br />
Setup acf for web administration<br />
{{Cmd|setup-acf}}<br />
<br />
== Setup Firewall ==<br />
{{Cmd|apk add acf-awall}}<br />
{{Todo|Need to lock down firewall rules}}<br />
<br />
==Install and Configure the Recursive DNS Service ==<br />
Install unbound package<br />
{{Cmd|apk add unbound}}<br />
With your favorite editor configure /etc/unbound/unbound.conf<br />
{{cat|/etc/unbound/unobund.conf|<br />
server:<br />
verbosity: 1<br />
interface: 172.17.48.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 172.17.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
}}<br />
== Install and Configure the Proxy service ==<br />
Install the necessary packages<br />
{{Cmd|apk add squid squark lighttpd}}<br />
With your preferred editor configure /etc/squid/squid.conf<br />
{{cat|/etc/squid/squid.conf|<br />
<pre><br />
#Squid config <br />
<br />
# This port listens for client requests<br />
http_port 172.17.48.1:8080 transparent<br />
http_port 127.0.0.1:8081<br />
<br />
visible_hostname wifi.local<br />
cache_mem 8 MB<br />
# If you don't have an HD installed comment the "cache_dir" line below<br />
cache_dir aufs /var/cache/squid 900 16 256<br />
<br />
# Even though we only use one proxy, this line is recommended<br />
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html<br />
hierarchy_stoplist cgi-bin ?<br />
<br />
# Keep 7 days of access logs<br />
logfile_rotate 7<br />
<br />
logformat squark %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %rG<br />
access_log /var/log/squid/access.log squark<br />
cache_store_log none<br />
pid_filename /var/run/squid.pid<br />
<br />
# Make sure client IP is passed to Squark<br />
log_uses_indirect_client on<br />
acl_uses_indirect_client on<br />
<br />
# Debugging Squid, see http://wiki.squid-cache.org/KnowledgeBase/DebugSections<br />
# for more info<br />
# Keep 7 days of cache log<br />
debug_options rotate=7<br />
<br />
# Web auditors want to see the full uri, even with the query terms<br />
strip_query_terms off<br />
<br />
refresh_pattern ^ftp: 1440 20% 10080<br />
refresh_pattern ^gopher: 1440 0% 1440<br />
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0<br />
refresh_pattern . 0 20% 4320<br />
<br />
coredump_dir /var/cache/squid<br />
<br />
dns_nameservers 172.17.48.1<br />
<br />
# <br />
# Authentication<br />
#<br />
# Squark external acl<br />
#external_acl_type squark_snmp_auth_D children-max=1 ttl=4 grace=1 negative_ttl=0 concurrency=128 %SRC /usr/bin/squark-auth-snmp -c public -R <SWITCH_IP> -i <D_VLAN_IF> -v <D_VLAN_ID> -f "%N-%i=%I" -T /etc/squark/topology.conf<br />
<br />
#<br />
# Access Control Lists (ACL's)<br />
#<br />
<br />
# Standard ACL settings<br />
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp<br />
acl to_localhost dst 172.17.48.1<br />
acl SSL_ports port 443 563 8004 9000<br />
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535<br />
acl purge method PURGE<br />
acl CONNECT method CONNECT<br />
<br />
#acl SquarkAuth external squark_auth<br />
#acl SquarkSnmpAuthD external squark_snmp_auth_D<br />
<br />
# Squark filter<br />
url_rewrite_program /usr/bin/squark-filter<br />
url_rewrite_children 1 concurrency=128<br />
<br />
# Require authentication<br />
acl userlist src all<br />
<br />
# Definition of zones<br />
acl Zone_D src 172.17.48.0/24<br />
<br />
<br />
#<br />
# Access restrictions<br />
#<br />
<br />
cache deny QUERY<br />
<br />
# Only allow cachemgr access from localhost<br />
http_access allow manager localhost<br />
http_access deny manager<br />
<br />
# Only allow purge requests from localhost<br />
http_access allow purge localhost<br />
http_access deny purge<br />
<br />
# Deny requests to unknown ports<br />
http_access deny !Safe_ports<br />
<br />
# Deny CONNECT to other than SSL ports<br />
http_access deny CONNECT !SSL_ports<br />
<br />
# Allow hosts in Zone_D to access the entire Internet<br />
http_access allow Zone_D<br />
<br />
# Denying all access not explictly allowed<br />
http_access deny all<br />
<br />
##Squark URL rewriter<br />
#Prevent squark from filtering itself<br />
url_rewrite_access deny manager<br />
url_rewrite_access deny to_localhost<br />
<br />
#Finally, permit access<br />
url_rewrite_access allow Zone_D<br />
<br />
http_reply_access allow all<br />
icp_access allow all<br />
</pre><br />
}}<br />
Configure lighttpd<br />
{{cat|/etc/lighttpd/lighttpd.conf|<br />
<pre><br />
var.basedir = "/var/www/localhost"<br />
var.logdir = "/var/log/lighttpd"<br />
var.statedir = "/var/lib/lighttpd"<br />
<br />
server.modules = (<br />
"mod_access",<br />
"mod_accesslog",<br />
"mod_extforward"<br />
)<br />
<br />
include "mime-types.conf"<br />
include "mod_cgi.conf"<br />
<br />
server.username = "lighttpd"<br />
server.groupname = "lighttpd"<br />
<br />
server.document-root = var.basedir + "/squark"<br />
server.pid-file = "/var/run/lighttpd.pid"<br />
<br />
server.errorlog = var.logdir + "/error.log"<br />
<br />
server.indexfiles = ("index.php", "index.html",<br />
"index.htm", "default.htm")<br />
<br />
<br />
server.follow-symlink = "enable"<br />
<br />
server.port = 81<br />
server.bind = "172.17.48.1"<br />
<br />
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")<br />
<br />
accesslog.filename = var.logdir + "/access.log"<br />
<br />
url.access-deny = ("~", ".inc")<br />
<br />
extforward.forwarder = ("172.17.48.1" => "trust")<br />
</pre><br />
}}<br />
{{cat|/etc/lighttpd/mod_cgi.conf|<br />
<pre><br />
###############################################################################<br />
# mod_cgi.conf<br />
# include'd by lighttpd.conf.<br />
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $<br />
###############################################################################<br />
<br />
#<br />
# see cgi.txt for more information on using mod_cgi<br />
#<br />
<br />
server.modules += ("mod_cgi")<br />
<br />
# NOTE: this requires mod_alias<br />
alias.url = (<br />
"/cgi-bin/" => var.basedir + "/cgi-bin/"<br />
)<br />
<br />
#<br />
# Note that you'll also want to enable the<br />
# cgi-bin alias via mod_alias (above).<br />
#<br />
<br />
$HTTP["url"] =~ "^/cgi-bin/" {<br />
# disable directory listings<br />
dir-listing.activate = "disable"<br />
# only allow cgi's in this directory<br />
cgi.assign = (<br />
".pl" => "/usr/bin/perl",<br />
".cgi" => "/usr/bin/haserl"<br />
)<br />
}<br />
<br />
# vim: set ft=conf foldmethod=marker et :<br />
</pre><br />
}}<br />
Link Squark web pages to the Web server home directory<br />
{{Cmd|ln -s /usr/share/squark/www/ /var/www/localhost/squark}}<br />
Make 'squid' and 'lighttpd' users member of the group squark<br />
{{Cmd|addgroup squid squark<br />
addgroup lighttpd squark}}<br />
Start lighttpd and configure the Web service to start at boot<br />
{{Cmd|/etc/init.d/lighttpd start<br />
rc-update add lighttpd}}<br />
Start Squid and configure it to start at boot<br />
{{Cmd|/etc/init.d/squid start<br />
rc-update add squid}}</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Include:Copying_Alpine_to_Flash&diff=10008
Include:Copying Alpine to Flash
2014-06-10T14:11:25Z
<p>Jbilyk: /* Manual */ optionally remove apkovl</p>
<hr />
<div>=== Boot Alpine Linux CD-ROM ===<br />
# Insert the Alpine Linux CD-ROM into a computer.<br />
# Boot the computer from the Alpine Linux CD-ROM.<br />
#* This step may require changes to the BIOS settings to select booting from CD. <br />
# Login with the username ''root''. No password is needed.<br />
<br />
{{Tip|If you're not able to boot from the CD, then another option is to boot from a regular Alpine installation, and [[Burning_ISOs|manually mount the ISO image to {{Path|/media/cdrom}}]].}} <br />
<br />
=== Determine the Device Name of the {{{1|Flash Medium}}} ===<br />
Determine the name your computer uses for your {{{1|flash medium}}}. The following step is one way to do this.<br />
# After inserting the {{{1|flash medium}}}, run the command:<br />
#* {{Cmd|dmesg}}<br />
#* At the end of this command you should see the name of your {{{1|flash medium}}}, likely starting with "sd". (For example: "sda").<br />
#* The remainder of this document will assume that your {{{1|flash medium}}} is called /dev/sda<br />
<br />
{{Warning|Be very careful about this. You do not want to mistakenly wipe your hard drive if it's on /dev/sda}}<br />
<br />
=== Format {{{1|Flash Medium}}} ===<br />
Run fdisk (replacing sda with your {{{1|flash medium}}} name):<br />
{{Cmd|fdisk /dev/sda}}<br />
<br />
# (''Optional'') - Create new partition table with one FAT32 partition<br />
#* '''d''' Delete all partitions (this may take a few steps)<br />
#* '''n''' Create a new partition<br />
#* '''p''' A primary partition<br />
#* '''1''' Partition number 1<br />
#** Use defaults for first and last cylinder (just press [Enter] twice).<br />
#* '''t''' Change partition type<br />
#* '''c''' Partition type (Win95 FAT32/LBA)<br />
#Verify that the primary partition is bootable<br />
#* '''p''' Print list of partitions<br />
#* If there is no '*' next to the first partition, follow the next steps:<br />
#** '''a''' <big>Make the partition bootable (set boot flag)</big><br />
#** '''1''' Partition number 1<br />
#'''w''' Write your changes to the device<br />
<br />
=== Add Alpine Linux to the {{{1|Flash Medium}}} ===<br />
To boot from your {{{1|flash medium}}} you need to copy the contents of the CDROM to the {{{1|flash medium}}} and make it bootable. Those two operations can be automated with the [[setup-bootable]] tool or can be done manually.<br />
<br />
{{Note|If the following commands fail due to 'No such file or directory', you may have to remove and reinsert the {{{1|flash medium}}}, or even reboot, to get /dev/sda1 to appear}}<br />
<br />
==== Automated ====<br />
{{Tip|If using Alpine Linux 1.10.4 or newer, you can use this section to complete the install. Otherwise, follow the Manual steps below.}}<br />
{{Note|The target partition has to be formatted. Use the <code>mkdosfs</code> command from the Manual steps below if needed.}}<br />
# Run the [[setup-bootable]] script to add Alpine Linux to the {{{1|flash medium}}} and make it bootable (replacing sda with your {{{1|flash medium}}} name):<br />
#: {{Cmd|setup-bootable /media/cdrom /dev/sda1}}<br />
{{Note|If you get something like '<code>Failed to mount /dev/sda1 on /media/sda1</code>' when running the above [[setup-bootable]] command, you might want to try running:<br />
{{Cmd|modprobe vfat}}<br />
and then try re-run the [[setup-bootable]] command as described above.}}<br />
{{Warning|If you are installing to a USB Stick, you may need to modify the {{Path|syslinux.cfg}} file to say <code>usbdisk</code> as [[#Wrong_Device_Name|described below]], or you will face possible problems booting and definite problems with the package cache. Recent versions of <code>setup-bootable</code> will specify the alpine_dev using a UUID instead, so it should work properly by default.}}<br />
<br />
==== Manual ====<br />
# (''Optional'') - If you created a new partition above, format the {{{1|flash medium}}} with a FAT32 filesystem (replacing sda with your {{{1|flash medium}}} name):<br />
#: {{Cmd|apk add dosfstools<BR>mkdosfs -F32 /dev/sda1}}<br />
# Install syslinux and MBR (replacing sda with your {{{1|flash medium}}} name):<br />
#: {{Cmd|{{{|apk add syslinux<BR>dd if=/usr/share/syslinux/mbr.bin of=/dev/sda}}}<BR>syslinux /dev/sda1}}<br />
#Copy the files to the {{{1|flash medium}}} (replacing sda with your {{{1|flash medium}}} name):<br />
#: {{Cmd|<nowiki>mkdir -p /media/sda1<br />
mount -t vfat /dev/sda1 /media/sda1<br />
cd /media/cdrom<br />
cp -a .alpine-release * /media/sda1/<br />
umount /media/sda1</nowiki>}}<br />
# (''Optional'') Remove any apkovl files that were transfered as part of the copy process. This should be done if you wish to have a fresh install. Replace sda with your {{{1|flash medium}}} name)<br />
#: {{Cmd|<nowiki>mount -t vfat /dev/sda1 /media/sda1<br />
rm /media/sda1/*.apkovl.tar.gz<br />
umount /media/sda1</nowiki>}}<br />
<br />
== Troubleshooting ==<br />
=== Wrong Device Name ===<br />
If you cannot boot from the {{{1|flash medium}}} and you see something like:<br />
Mounting boot media failed.<br />
initramfs emergency recovery shell launched. Type 'exit' to continue boot<br />
then it is likely that the device name in {{Path|syslinux.cfg}} is wrong. You should replace the device name in this line:<br />
append initrd=/boot/grsec.gz alpine_dev='''usbdisk''':vfat modules=loop,cramfs,sd-mod,usb-storage quiet<br />
with the proper device name.<br />
* For boot from USB, the device name should be 'usbdisk' (as shown above)<br />
* For other options, you can run <code>cat /proc/partitions</code> to see the available disks (i.e. 'sda' or 'sdb')<br />
<br />
=== Non-FAT32 Filesystems ===<br />
When your {{{1|flash medium}}} is formatted with a filesystem other than FAT32, you might have to specify the necessary filesystem modules in the boot parameters.<br />
<br />
To do so, mount the {{{1|flash medium}}} and change the {{Path|syslinux.cfg}} file line from <br />
append initrd=/boot/grsec.gz alpine_dev=usbdisk:vfat modules=loop,cramfs,sd-mod,usb-storage quiet<br />
to<br />
append initrd=/boot/grsec.gz alpine_dev=usbdisk:'''ext3''' modules=loop,cramfs,sd-mod,usb-storage''',ext3''' quiet<br />
in the case of an ext3 formatted partition. A similar procedure might apply to other filesystems (if they are supported by syslinux and the Alpine Linux kernel).</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&diff=9843
Tutorials and Howtos
2014-02-17T20:29:11Z
<p>Jbilyk: /* Complete Solutions */</p>
<hr />
<div>[[Image:package_edutainment.svg|right|link=]]<br />
{{TOC left}}<br />
'''Welcome to Tutorials and Howtos, a place of basic and advanced configuration tasks for your Alpine Linux.'''<br />
<br />
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.<br />
<br />
Howtos are smaller articles explaining how to perform a particular task with Alpine Linux.<br />
<br />
We encourage people to send in both complete articles as well as requesting topics to be covered. If you think you have the skills and knowledge to write an Alpine Linux related article please do so on this Wiki. If you want to request a topic, please add your request in this page's [[Talk:Tutorials_and_Howtos|Discussion]].<br />
<br />
{{Clear}}<br />
== Storage ==<br />
<br />
* [[Alpine local backup|Alpine local backup (lbu)]] ''(Permanently store your modifications in case your box needs reboot)'' <!-- Installation and Storage --><br />
** [[Back Up a Flash Memory Installation]] <!-- Installation and Storage --><br />
** [[Manually editing a existing apkovl]]<br />
<br />
* [[Setting up disks manually]] <!-- Installation and Storage --><br />
* [[Setting up a software RAID1 array]]<br />
<!-- ** [[Setting up a /var partition on software IDE raid1]] Obsolete, Installation and Storage --> <br />
* [[Raid Administration]]<br />
* [[Setting up encrypted volumes with LUKS]]<br />
* [[Setting up Logical Volumes with LVM]]<br />
** [[Setting up LVM on GPT-labeled disks]]<br />
* [[Filesystems|Formatting HD/Floppy/Other]] <!-- just a stub --><br />
<br />
* [[Setting up iSCSI]]<br />
** [[iSCSI Raid and Clustered File Systems]]<br />
* [[High performance SCST iSCSI Target on Linux software Raid]] ''(deprecated)'' <!-- solution --><br />
* [[Linux iSCSI Target (TCM)]]<br />
* [[Disk Replication with DRBD]] <!-- draft --><br />
<br />
* [[Burning ISOs]] <!-- just some links now --><br />
* [[Bootmanagers]]<br />
* [[Migrating data]]<br />
<br />
== Networking ==<br />
<br />
* [[Configure Networking]]<br />
* [[Connecting to a wireless access point]]<br />
* [[Bonding]]<br />
* [[Vlan]]<br />
* [[Bridge]]<br />
* [[How to configure static routes]]<br />
<br />
* [[Alpine Wall]] - [[How-To Alpine Wall]] - [[Alpine Wall User's Guide]] ''(a new firewall management framework)''<br />
<br />
* [[Using serial modem]]<br />
* [[Using HSDPA modem]]<br />
* [[Setting up Satellite Internet Connection]]<br />
* [[Using Alpine on Windows domain with IPSEC isolation]]<br />
<br />
* [[Setting up a ssh-server]] ''(Using ssh is a good way to administer your box remotely)'' <!-- Server and Networking --><br />
* [[How to setup a wireless access point]] ''(Setting up Secure Wireless AP w/ WPA encryption with bridge to wired network)''<br />
* [[Setting up a OpenVPN server with Alpine]] ''(Allowing single users or devices to remotely connect to your network)''<br />
<!-- [[Using Racoon for Remote Sites]] is a different VPN tunnelling method, but that article is just a stub --><br />
* [[Experiences with OpenVPN-client on ALIX.2D3]] <!-- solution --><br />
<br />
* [[Generating SSL certs with ACF]] <!-- Generating SSL certs with ACF 1.9 --><br />
* [[Setting up unbound DNS server]]<br />
* [[Setting up nsd DNS server]]<br />
* [[TinyDNS Format]]<br />
* [[Fault Tolerant Routing with Alpine Linux]] <!-- solution --><br />
* [[Freeradius Active Directory Integration]]<br />
* [[Multi_ISP]] ''(Dual-ISP setup with load-balancing and automatic failover)''<br />
* [[OwnCloud]] ''(Installing OwnCloud)''<br />
<br />
== Post-Install ==<br />
<!-- If you edit this, please coordinate with Installation#Post-Install and Developer_Documentation#Package_management. Note that these three sections are not exact duplicates. --><br />
<br />
* [[Alpine Linux package management|Package Management (apk)]] ''(How to add/remove packages on your Alpine)''<br />
<!-- [[Alpine Linux package management#Local_Cache|How to enable APK caching]] --><br />
** [[Comparison with other distros]]<br />
* [[Alpine local backup|Alpine local backup (lbu)]] ''(Permanently store your modifications in case your box needs reboot)''<br />
** [[Back Up a Flash Memory Installation]] <!-- new --><br />
** [[Manually editing a existing apkovl]]<br />
* [[Alpine Linux Init System|Init System (OpenRC)]] ''(Configure a service to automatically boot at next reboot)''<br />
** [[Multiple Instances of Services]]<br />
<!-- [[Writing Init Scripts]] --><br />
* [[Upgrading Alpine]]<br />
<!-- Obsolete<br />
[[Upgrading Alpine - v1.9.x]]<br />
[[Upgrading Alpine - CD v1.8.x]]<br />
[[Upgrading Alpine - HD v1.8.x]]<br />
[[Upgrade to repository main|Upgrading to signed repositories]]<br />
--><br />
<br />
* [[Setting up a ssh-server]] ''(Using ssh is a good way to administer your box remotely)''<br />
* [[setup-acf]] ''(Configures ACF (webconfiguration) so you can manage your box through https)''<br />
* [[Changing passwords for ACF|Changing passwords]]<br />
* [[Ansible]] ''(Configuration management)''<br />
<br />
* [[Enable Serial Console on Boot]]<br />
* [[Error message on boot: Address space collision: host bridge window conflicts with Adaptor ROM]]<br />
<br />
== Desktop Environment ==<br />
<br />
* [[XFCE Setup]] and [[Xfce Desktop|Desktop Ideas]]<br />
* [[EyeOS]] ''(Cloud Computing Desktop)''<br />
* [[Oneye]] ''(Cloud Computing Desktop - Dropbox Alternative)''<br />
* [[Owncloud]] ''(Cloud Computing Desktop - Dropbox Alternative)''<br />
** (to be merged with [[OwnCloud]] ''(Your personal Cloud for storing and sharing your data on-line)'')<br />
* [[Gnome Setup]]<br />
* [[Awesome(wm) Setup]]<br />
<br />
== Applications ==<br />
<br />
=== Telephony ===<br />
* [[Setting up Zaptel/Asterisk on Alpine]]<br />
** [[Setting up Streaming an Asterisk Channel]]<br />
* [[Freepbx on Alpine Linux]]<br />
* [[FreePBX_V3]] ''(FreeSWITCH, Asterisk GUI web acces tool)''<br />
* [[2600hz]] ''(FreeSWITCH, Asterisk GUI web access tool)''<br />
* [[Kamailio]] ''(SIP Server, formerly OpenSER)''<br />
<br />
=== Mail ===<br />
* [[Hosting services on Alpine]] ''(Hosting mail, webservices and other services)''<br />
** [[Hosting Web/Email services on Alpine]]<br />
* [[ISP Mail Server HowTo]] <!-- solution, Mail --><br />
** [[ISP Mail Server Upgrade 2.x]]<br />
** [[ISP Mail Server 2.x HowTo]] ''(Beta, please test)''<br />
* [[Roundcube]] ''(Webmail system)''<br />
* [[Setting up postfix with virtual domains]]<br />
* [[Protecting your email server with Alpine]]<br />
* [[Setting up clamsmtp]]<br />
* [[Setting up dovecot with imap and ssl]]<br />
<br />
=== HTTP ===<br />
* [[Lighttpd]]<br />
** [[Lighttpd Https access]]<br />
** [[Setting Up Lighttpd with PHP]]<br />
** [[Setting Up Lighttpd With FastCGI]]<br />
* [[Cherokee]]<br />
* [[Nginx]]<br />
* [[Apache]]<br />
** [[Setting Up Apache with PHP]]<br />
** [[Apache authentication: NTLM Single Signon]]<br />
<br />
* [[High Availability High Performance Web Cache]] ''(uCarp + HAProxy for High Availability Services such as Squid web proxy)'' <!-- solution, Server --><br />
<br />
* [[Setting up Transparent Squid Proxy]] <!-- draft --><br />
** [[SqStat]] ''(Script to look at active squid users connections)''<br />
** [[Obtaining user information via SNMP]] ''(Using squark-auth-snmp as a Squid authentication helper)'' <!-- Networking and Server, <== Using squark-auth-snmp --><br />
* [[Setting up Explicit Squid Proxy]]<br />
<br />
* [[Drupal]] ''(Content Management System (CMS) written in PHP)''<br />
* [[WordPress]] ''(Web software to create website or blog)''<br />
* [[MediaWiki]] ''(Free web-based wiki software application)''<br />
* [[DokuWiki]]<br />
* [[Darkhttpd]]<br />
<br />
=== Other Servers ===<br />
* [[Setting up a ssh-server]] ''(Using ssh is a good way to administer your box remotely)''<br />
<br />
* [[Phpizabi]] ''(Social Networking Platform)''<br />
* [[Statusnet]] ''(Microblogging Platform)''<br />
* [[Pastebin]] ''(Pastebin software application)''<br />
* [[Setting up Transmission (bittorrent) with Clutch WebUI]]<br />
<br />
* [[Redmine]] ''(Project management system)''<br />
* [[Request-Tracker]] ''(Ticket system)''<br />
* [[OsTicket]] ''(Ticket system)''<br />
* [[Setting up trac wiki|Trac]] ''(Enhanced wiki and issue tracking system for software development projects)''<br />
<br />
* [[Cgit]]<br />
** [[Setting up a git repository server with gitolite and cgit]] <!-- doesn't exist yet --><br />
* [[Roundcube]] ''(Webmail system)''<br />
* [[Glpi]] ''(Manage inventory of technical resources)''<br />
<br />
* [[How to setup a Alpine Linux mirror]]<br />
* [[Cups]]<br />
* [[NgIRCd]] ''(Server for Internet Relay Chat/IRC)''<br />
* [[OpenVCP]] ''(VServer Control Panel)''<br />
* [[Mahara]] ''(E-portfolio and social networking system)''<br />
* [[Chrony and GPSD | Using chrony, gpsd, and a garmin LVC 18 as a Stratum 1 NTP source ]]<br />
* [[Sending SMS using gnokii]]<br />
<br />
=== Monitoring ===<br />
* [[Traffic monitoring]] <!-- Networking and Monitoring --><br />
* [[Setting up traffic monitoring using rrdtool (and snmp)]] <!-- Monitoring --><br />
* [[Setting up monitoring using rrdtool (and rrdcollect)]]<br />
* [[Setting up Cacti|Cacti]] ''(Front-end for rrdtool networking monitor)''<br />
* [[Setting up Zabbix|Zabbix]] ''(Monitor and track the status of network services and hardware)''<br />
* [[Setting up A Network Monitoring and Inventory System]] ''(Nagios + OpenAudit and related components)'' <!-- draft, solution, Networking and Monitoring and Server --><br />
** [[Setting up NRPE daemon]] ''(Performs remote Nagios checks)'' <!-- Networking and Monitoring --><br />
* [[Setting up Smokeping|Smokeping]] ''(Network latency monitoring)'' <!-- Networking and Monitoring --><br />
** [[Setting up MRTG and Smokeping to Monitor Bandwidth Usage and Network Latency]]<br />
* [[Setting Up Fprobe And Ntop|Ntop]] ''(NetFlow collection and analysis using a remote fprobe instance)'' <!-- Networking and Monitoring --><br />
* [[Cvechecker]] ''(Compare installed packages for Common Vulnerabilities Exposure)'' <!-- Monitoring and Security --><br />
<br />
* [[IP Accounting]] <!-- Networking and Monitoring --><br />
* [[Obtaining user information via SNMP]] ''(Using squark-auth-snmp as a Squid authentication helper)'' <!-- Networking and Server, <== Using squark-auth-snmp --><br />
* [[SqStat]] ''(Script to look at active squid users connections)''<br />
<br />
* [[Piwik]] ''(A real time web analytics software program)''<br />
* [[Awstats]] ''(Free log file analyzer)''<br />
* [[Intrusion Detection using Snort]]<br />
** [[Intrusion Detection using Snort, Sguil, Barnyard and more]]<br />
* [[Dglog]] ''(Log analyzer for the web content filter DansGuardian)''<br />
<br />
* [[Webmin]] ''(A web-based interface for Linux system)''<br />
* [[PhpPgAdmin]] ''(Web-based administration tool for PostgreSQL)''<br />
* [[PhpMyAdmin]] ''(Web-based administration tool for MYSQL)''<br />
* [[PhpSysInfo]] ''(A simple application that displays information about the host it's running on)''<br />
* [[Linfo]]<br />
<br />
* [[Setting up lm_sensors]]<br />
<br />
== Misc ==<br />
<br />
* [[:Category:Shell]]<br />
* [[:Category:Programming]]<br />
* [[Running glibc programs]]<br />
* [[:Category:Drivers]]<br />
* [[:Category:Multimedia]]<br />
<br />
== Complete Solutions ==<br />
* [[Replacing non-Alpine Linux with Alpine remotely]]<br />
* [[High performance SCST iSCSI Target on Linux software Raid]]<br />
* [[Fault Tolerant Routing with Alpine Linux]]<br />
* [[Experiences with OpenVPN-client on ALIX.2D3]]<br />
<br />
* [[ISP Mail Server HowTo]] ''(Postfix+PostfixAdmin+DoveCot+Roundcube+ClamAV+Spamd - A full-serivce ISP mail server)''<br />
** [[ISP Mail Server Upgrade 2.x]]<br />
** [[ISP Mail Server 2.x HowTo]] ''(Beta, please test)''<br />
* [[High Availability High Performance Web Cache]] ''(uCarp + HAProxy for High Availability Services such as Squid web proxy)''<br />
* [[Setting up A Network Monitoring and Inventory System]] ''(Nagios + OpenAudit and related components)'' <!-- draft --><br />
* [[Streaming Security Camera Video with VLC]]<br />
* [[Dynamic Multipoint VPN (DMVPN)]] combined with [[Small_Office_Services]]<br />
<br />
<br />
<!--<br />
This does not attempt to be complete. Is it useful to have these listed here? I find them more accessible if grouped with their topics; also, an up-to-date list of all Draft or Obsolete pages can be found at [[Project:Wiki maintenance]].<br />
<br />
== Drafts ==<br />
Currently unfinished/works-in-progress.<br />
* [[Using Racoon for Remote Sites]]<br />
* [[Setting up Transparent Squid Proxy]] ''(Covers Squid proxy and URL Filtering system)''<br />
** [[Obtaining user information via SNMP]] ''(Using the Squark Squid authentication helper)'' [!-- no longer a draft --]<br />
* [[Setting up Streaming an Asterisk Channel]]<br />
* [[Setting up A Network Monitoring and Inventory System]] ''(Nagios + OpenAudit and related components)''<br />
* [[Intrusion Detection using Snort]] ''(Installing and configuring Snort and related applications on Alpine 2.0.x)''<br />
* [[IP Accounting]] ''(Installing and configuring pmacct for IP Accounting, Netflow/sFlow collector)''<br />
* [[Disk Replication with DRBD]]<br />
--></div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9331
Dynamic Multipoint VPN (DMVPN)
2013-08-26T13:24:55Z
<p>Jbilyk: /* Firewall */ add modprobe</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Extract Certificates =<br />
We will use certificates for DMVPN and for OpenVPN (RoadWarrior clients). Here are the general purpose instruction for extracting certificates from pfx files:<br />
<br />
{{Cmd|openssl pkcs12 -in cert.pfx -cacerts -nokeys -out cacert.pem<br />
openssl pkcs12 -in cert.pfx -nocerts -nodes -out serverkey.pem<br />
openssl pkcs12 -in cert.pfx -nokeys -clcerts -out cert.pem<br />
}}<br />
<br />
Remember to set appropriate permission for your certificate files:<br />
<br />
{{Cmd|chmod 600 *.pem *.pfx}}<br />
<br />
= Spoke Node =<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Physically install ==<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to eth0. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== SSH ==<br />
Remove password authentication and DNS reverse lookup:<br />
{{Cmd|sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add -U unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Start unbound:<br />
<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
<br />
<pre><br />
auto bond0.8<br />
...<br />
...<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
</pre><br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
nsdc rebuild<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor create <code>/etc/ipsec.conf</code> and set the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
{{Cmd|mkdir /etc/racoon/}}<br />
<br />
Extract your pfx into /etc/racoon, using the filenames '''ca.pem''', '''cert.pem''', and '''key.pem'''.<br />
<br />
With your favorite editor create <code>/etc/racoon/racoon.conf</code> and set the content to the following:<br />
<br />
<pre><br />
path certificate "/etc/racoon/";<br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Edit /etc/conf.d/racoon and unset RACOON_PSK_FILE:<br />
<br />
<pre><br />
...<br />
RACOON_PSK_FILE=<br />
...<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start<br />
rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=$(sed -n 's/router bgp \(\d*\)/\1/p' < /etc/quagga/bgpd.conf)<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script<br />
/etc/init.d/opennhrp start<br />
rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga<br />
touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start<br />
rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
{{Cmd|echo tun >> /etc/modules<br />
modprobe tun<br />
apk add openvpn openssl<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start<br />
rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/openvpn.json'''</code><br />
<pre><br />
{<br />
"description": "OpenVPN support",<br />
<br />
"import": "internet-host",<br />
<br />
"service": { <br />
"openvpn": { "proto": "udp", "port": 1194 }<br />
},<br />
<br />
"filter": [ <br />
{ "in": "E", "out": "_fw", "service": "openvpn", "action": "accept" }<br />
]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/clampmss.json'''</code><br />
<pre><br />
{<br />
"description": "Deal with ISPs afraid of ICMP",<br />
<br />
"import": "internet-host",<br />
<br />
"clamp-mss": [ { "out": "E" } ]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|modprobe ip_tables<br />
modprobe iptable_nat <br />
awall enable clampmss<br />
awall enable openvpn<br />
awall enable vpnc<br />
awall activate<br />
rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu<br />
echo -e "1\tisp1">> /etc/iproute2/rt_tables<br />
echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
fwmark 1<br />
rule-priority 20000<br />
# google dns<br />
ping 8.8.8.8<br />
# opendns<br />
ping 208.67.222.222<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
fwmark 2<br />
rule-priority 20000<br />
}<br />
<br />
</pre><br />
<br />
Make sure we can reach the public IP from our LAN by adding static route rules for our private net(s). Edit <code>/etc/pingu/route-rules</code>:<br />
<pre><br />
to 10.0.0.0/8 table main prio 1000<br />
to 172.16.0.0/12 table main prio 1000<br />
</pre><br />
<br />
Start pingu:<br />
{{Cmd|/etc/init.d/pingu start<br />
rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
We will document only what changes from the Spoke node setup.<br />
<br />
== Routing Tables ==<br />
{{Cmd|echo -e "42\tnhrp_shortcut\n43\tnhrp_mtu\n44\tquagga\n}}<br />
<br />
== NHRP ==<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
interface gre1<br />
map %Hub1_GRE_IP%/%MaskBit% hub1.example.org<br />
route-table 44<br />
shortcut<br />
redirect<br />
non-caching<br />
</pre><br />
Do the same on Hub 1 adding the data relative to Hub 2.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and set the content as follows:<br />
<pre><br />
#!/bin/sh<br />
<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -t opennhrp-script -p auth.err "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
logger -t opennhrp-script -p auth.info "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA authenticated"<br />
<br />
(<br />
flock -x 200<br />
<br />
AS=`echo "$CERT" | grep "^AS=" | cut -b 4-`<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "router bgp 65000" \<br />
-c "neighbor $NHRP_DESTADDR remote-as $AS" \<br />
-c "neighbor $NHRP_DESTADDR peer-group leaf" \<br />
-c "neighbor $NHRP_DESTADDR prefix-list net-$AS-in in"<br />
<br />
SEQ=5<br />
(echo "$CERT" | grep "^NET=" | cut -b 5-) | while read NET; do<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "ip prefix-list net-$AS-in seq $SEQ permit $NET le 26"<br />
SEQ=$(($SEQ+5))<br />
done<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
peer-up)<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -p daemon.err "GRE mapping of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU table nhrp_mtu<br />
fi<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42 table nhrp_mtu<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</pre><br />
<br />
== BGP ==<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
password zebra<br />
enable password zebra<br />
log syslog<br />
<br />
router bgp 65000<br />
bgp router-id %Hub2_GRE_IP%<br />
bgp deterministic-med<br />
network %GRE_NETWORK%/%MASK_BITS%<br />
neighbor hub peer-group<br />
neighbor hub next-hop-self<br />
neighbor hub route-map CORE-IN in<br />
neighbor spoke peer-group<br />
neighbor spoke passive<br />
neighbor spoke next-hop-self<br />
neighbor %Spoke1_GRE_IP% remote-as 65001<br />
neighbor %Spoke1_GRE_IP% peer-group spoke<br />
neighbor %Spoke1_GRE_IP% prefix-list net-65001-in in<br />
...<br />
...<br />
...<br />
<br />
neighbor hub remote-as 65000<br />
neighbor %Hub1_GRE_IP% peer-group core<br />
<br />
ip prefix-list net-65001-in seq 5 permit 10.1.0.0/16 le 26<br />
...<br />
<br />
route-map CORE-IN permit 10<br />
set metric +100<br />
</pre><br />
<br />
Add the lines <code>neighbor %Spoke1_GRE_IP%...</code> for each spoke node you have. Do the same on Hub 1, changing the relevant data for Hub 2.<br />
<br />
= Troubleshooting the DMVPN =<br />
== Broken [http://en.wikipedia.org/wiki/Path_MTU_Discovery Path MTU Discovery (PMTUD)] ==<br />
ISPs afraid of ICMP (which is somehow legitimate) often just blindly add <code>no ip unreachables</code> in their router interfaces, effectively creating a [http://en.wikipedia.org/wiki/Black_hole_%28networking%29 blackhole router] that breaks PMTUD, since ICMP Type 3 Code 4 packets (Fragmentation Needed) are dropped. PMTUD is needed by ISAKMP that runs on UDP (TCP works because it uses CLAMPMSS).<br />
<br />
For technical details see http://packetlife.net/blog/2008/oct/9/disabling-unreachables-breaks-pmtud/<br />
<br />
PMTUD could also be broken due to badly configured DSL modem/routers or bugged firmware.<br />
<br />
You can easily detect which host is the blackhole router by pinging with DF bit set and with packets of standard MTU size, each hop given in your traceroute to destination:<br />
<br />
{{Cmd|ping -M do -s 1472 %IP%}}<br />
{{Note|"-M do" requires GNU ping, present in <code>iputils</code> package}}<br />
<br />
If you don't get a response back (either Echo-Response or Fragmentation-Needed) there's firewall dropping ICMP packets. If it answers to normal ping packets (DF bit cleared), most likely you have hit a blackhole router.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9325
Dynamic Multipoint VPN (DMVPN)
2013-08-23T18:20:57Z
<p>Jbilyk: /* Firewall */ add openvpn firewall rules</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Extract Certificates =<br />
We will use certificates for DMVPN and for OpenVPN (RoadWarrior clients). Here are the general purpose instruction for extracting certificates from pfx files:<br />
<br />
{{Cmd|openssl pkcs12 -in cert.pfx -cacerts -nokeys -out cacert.pem<br />
openssl pkcs12 -in cert.pfx -nocerts -nodes -out serverkey.pem<br />
openssl pkcs12 -in cert.pfx -nokeys -clcerts -out cert.pem<br />
}}<br />
<br />
Remember to set appropriate permission for your certificate files:<br />
<br />
{{Cmd|chmod 600 *.pem *.pfx}}<br />
<br />
= Spoke Node =<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Physically install ==<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to eth0. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== SSH ==<br />
Remove password authentication and DNS reverse lookup:<br />
{{Cmd|sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add -U unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Start unbound:<br />
<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
<br />
<pre><br />
auto bond0.8<br />
...<br />
...<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
</pre><br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
nsdc rebuild<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor create <code>/etc/ipsec.conf</code> and set the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
{{Cmd|mkdir /etc/racoon/}}<br />
<br />
Extract your pfx into /etc/racoon, using the filenames '''ca.pem''', '''cert.pem''', and '''key.pem'''.<br />
<br />
With your favorite editor create <code>/etc/racoon/racoon.conf</code> and set the content to the following:<br />
<br />
<pre><br />
path certificate "/etc/racoon/";<br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Edit /etc/conf.d/racoon and unset RACOON_PSK_FILE:<br />
<br />
<pre><br />
...<br />
RACOON_PSK_FILE=<br />
...<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start<br />
rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=$(sed -n 's/router bgp \(\d*\)/\1/p' < /etc/quagga/bgpd.conf)<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script<br />
/etc/init.d/opennhrp start<br />
rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga<br />
touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start<br />
rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
{{Cmd|echo tun >> /etc/modules<br />
modprobe tun<br />
apk add openvpn openssl<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start<br />
rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/openvpn.json'''</code><br />
<pre><br />
{<br />
"description": "OpenVPN support",<br />
<br />
"import": "internet-host",<br />
<br />
"service": { <br />
"openvpn": { "proto": "udp", "port": 1194 }<br />
},<br />
<br />
"filter": [ <br />
{ "in": "E", "out": "_fw", "service": "openvpn", "action": "accept" }<br />
]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/clampmss.json'''</code><br />
<pre><br />
{<br />
"description": "Deal with ISPs afraid of ICMP",<br />
<br />
"import": "internet-host",<br />
<br />
"clamp-mss": [ { "out": "E" } ]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall enable clampmss<br />
awall enable openvpn<br />
awall enable vpnc<br />
awall activate<br />
rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu<br />
echo -e "1\tisp1">> /etc/iproute2/rt_tables<br />
echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
fwmark 1<br />
rule-priority 20000<br />
# google dns<br />
ping 8.8.8.8<br />
# opendns<br />
ping 208.67.222.222<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
fwmark 2<br />
rule-priority 20000<br />
}<br />
<br />
</pre><br />
<br />
Make sure we can reach the public IP from our LAN by adding static route rules for our private net(s). Edit <code>/etc/pingu/route-rules</code>:<br />
<pre><br />
to 10.0.0.0/8 table main prio 1000<br />
to 172.16.0.0/12 table main prio 1000<br />
</pre><br />
<br />
Start pingu:<br />
{{Cmd|/etc/init.d/pingu start<br />
rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
We will document only what changes from the Spoke node setup.<br />
<br />
== Routing Tables ==<br />
{{Cmd|echo -e "42\tnhrp_shortcut\n43\tnhrp_mtu\n44\tquagga\n}}<br />
<br />
== NHRP ==<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
interface gre1<br />
map %Hub1_GRE_IP%/%MaskBit% hub1.example.org<br />
route-table 44<br />
shortcut<br />
redirect<br />
non-caching<br />
</pre><br />
Do the same on Hub 1 adding the data relative to Hub 2.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and set the content as follows:<br />
<pre><br />
#!/bin/sh<br />
<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -t opennhrp-script -p auth.err "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
logger -t opennhrp-script -p auth.info "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA authenticated"<br />
<br />
(<br />
flock -x 200<br />
<br />
AS=`echo "$CERT" | grep "^AS=" | cut -b 4-`<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "router bgp 65000" \<br />
-c "neighbor $NHRP_DESTADDR remote-as $AS" \<br />
-c "neighbor $NHRP_DESTADDR peer-group leaf" \<br />
-c "neighbor $NHRP_DESTADDR prefix-list net-$AS-in in"<br />
<br />
SEQ=5<br />
(echo "$CERT" | grep "^NET=" | cut -b 5-) | while read NET; do<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "ip prefix-list net-$AS-in seq $SEQ permit $NET le 26"<br />
SEQ=$(($SEQ+5))<br />
done<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
peer-up)<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -p daemon.err "GRE mapping of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU table nhrp_mtu<br />
fi<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42 table nhrp_mtu<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</pre><br />
<br />
== BGP ==<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
password zebra<br />
enable password zebra<br />
log syslog<br />
<br />
router bgp 65000<br />
bgp router-id %Hub2_GRE_IP%<br />
bgp deterministic-med<br />
network %GRE_NETWORK%/%MASK_BITS%<br />
neighbor hub peer-group<br />
neighbor hub next-hop-self<br />
neighbor hub route-map CORE-IN in<br />
neighbor spoke peer-group<br />
neighbor spoke passive<br />
neighbor spoke next-hop-self<br />
neighbor %Spoke1_GRE_IP% remote-as 65001<br />
neighbor %Spoke1_GRE_IP% peer-group spoke<br />
neighbor %Spoke1_GRE_IP% prefix-list net-65001-in in<br />
...<br />
...<br />
...<br />
<br />
neighbor hub remote-as 65000<br />
neighbor %Hub1_GRE_IP% peer-group core<br />
<br />
ip prefix-list net-65001-in seq 5 permit 10.1.0.0/16 le 26<br />
...<br />
<br />
route-map CORE-IN permit 10<br />
set metric +100<br />
</pre><br />
<br />
Add the lines <code>neighbor %Spoke1_GRE_IP%...</code> for each spoke node you have. Do the same on Hub 1, changing the relevant data for Hub 2.<br />
<br />
= Troubleshooting the DMVPN =<br />
== Broken [http://en.wikipedia.org/wiki/Path_MTU_Discovery Path MTU Discovery (PMTUD)] ==<br />
ISPs afraid of ICMP (which is somehow legitimate) just blindly add <code>no ip unreachables</code> in their router interfaces, effectively creating a [http://en.wikipedia.org/wiki/Black_hole_%28networking%29 blackhole router] that breaks PMTUD, since ICMP Type 3 Code 4 packets (Fragmentation Needed) are dropped. PMTUD is needed by ISAKMP that runs on UDP (TCP works because it uses CLAMPMSS).<br />
<br />
For technical details see http://packetlife.net/blog/2008/oct/9/disabling-unreachables-breaks-pmtud/<br />
<br />
PMTUD could also be broken due to badly configured DSL modem/routers or bugged firmware.<br />
<br />
You can easily detect which host is the blackhole router by pinging with DF bit set and with packets of standard MTU size, each hop given in your traceroute to destination:<br />
<br />
{{Cmd|ping -M do -s 1472 %IP%}}<br />
{{Note|"-M do" requires GNU ping, present in <code>iputils</code> package}}<br />
<br />
If you don't get a response back (either Echo-Response or Fragmentation-Needed) there's firewall dropping ICMP packets. If it answers to normal ping packets (DF bit cleared), most likely you have hit a blackhole router.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9324
Dynamic Multipoint VPN (DMVPN)
2013-08-23T15:53:44Z
<p>Jbilyk: /* OpenVPN */</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Extract Certificates =<br />
We will use certificates for DMVPN and for OpenVPN (RoadWarrior clients). Here are the general purpose instruction for extracting certificates from pfx files:<br />
<br />
{{Cmd|openssl pkcs12 -in cert.pfx -cacerts -nokeys -out cacert.pem<br />
openssl pkcs12 -in cert.pfx -nocerts -nodes -out serverkey.pem<br />
openssl pkcs12 -in cert.pfx -nokeys -clcerts -out cert.pem<br />
}}<br />
<br />
Remember to set appropriate permission for your certificate files:<br />
<br />
{{Cmd|chmod 600 *.pem *.pfx}}<br />
<br />
= Spoke Node =<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Physically install ==<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to eth0. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== SSH ==<br />
Remove password authentication and DNS reverse lookup:<br />
{{Cmd|sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add -U unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Start unbound:<br />
<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
<br />
<pre><br />
auto bond0.8<br />
...<br />
...<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
</pre><br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
nsdc rebuild<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor create <code>/etc/ipsec.conf</code> and set the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
{{Cmd|mkdir /etc/racoon/}}<br />
<br />
Extract your pfx into /etc/racoon, using the filenames '''ca.pem''', '''cert.pem''', and '''key.pem'''.<br />
<br />
With your favorite editor create <code>/etc/racoon/racoon.conf</code> and set the content to the following:<br />
<br />
<pre><br />
path certificate "/etc/racoon/";<br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Edit /etc/conf.d/racoon and unset RACOON_PSK_FILE:<br />
<br />
<pre><br />
...<br />
RACOON_PSK_FILE=<br />
...<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start<br />
rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=$(sed -n 's/router bgp \(\d*\)/\1/p' < /etc/quagga/bgpd.conf)<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script<br />
/etc/init.d/opennhrp start<br />
rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga<br />
touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start<br />
rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
{{Cmd|echo tun >> /etc/modules<br />
modprobe tun<br />
apk add openvpn openssl<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start<br />
rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/clampmss.json'''</code><br />
<pre><br />
{<br />
"description": "Deal with ISPs afraid of ICMP",<br />
<br />
"import": "internet-host",<br />
<br />
"clamp-mss": [ { "out": "E" } ]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall enable clampmss<br />
awall enable vpnc<br />
awall activate<br />
rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu<br />
echo -e "1\tisp1">> /etc/iproute2/rt_tables<br />
echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
fwmark 1<br />
rule-priority 20000<br />
# google dns<br />
ping 8.8.8.8<br />
# opendns<br />
ping 208.67.222.222<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
fwmark 2<br />
rule-priority 20000<br />
}<br />
<br />
</pre><br />
<br />
Make sure we can reach the public IP from our LAN by adding static route rules for our private net(s). Edit <code>/etc/pingu/route-rules</code>:<br />
<pre><br />
to 10.0.0.0/8 table main prio 1000<br />
to 172.16.0.0/12 table main prio 1000<br />
</pre><br />
<br />
Start pingu:<br />
{{Cmd|/etc/init.d/pingu start<br />
rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
We will document only what changes from the Spoke node setup.<br />
<br />
== Routing Tables ==<br />
{{Cmd|echo -e "42\tnhrp_shortcut\n43\tnhrp_mtu\n44\tquagga\n}}<br />
<br />
== NHRP ==<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
interface gre1<br />
map %Hub1_GRE_IP%/%MaskBit% hub1.example.org<br />
route-table 44<br />
shortcut<br />
redirect<br />
non-caching<br />
</pre><br />
Do the same on Hub 1 adding the data relative to Hub 2.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and set the content as follows:<br />
<pre><br />
#!/bin/sh<br />
<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -t opennhrp-script -p auth.err "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
logger -t opennhrp-script -p auth.info "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA authenticated"<br />
<br />
(<br />
flock -x 200<br />
<br />
AS=`echo "$CERT" | grep "^AS=" | cut -b 4-`<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "router bgp 65000" \<br />
-c "neighbor $NHRP_DESTADDR remote-as $AS" \<br />
-c "neighbor $NHRP_DESTADDR peer-group leaf" \<br />
-c "neighbor $NHRP_DESTADDR prefix-list net-$AS-in in"<br />
<br />
SEQ=5<br />
(echo "$CERT" | grep "^NET=" | cut -b 5-) | while read NET; do<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "ip prefix-list net-$AS-in seq $SEQ permit $NET le 26"<br />
SEQ=$(($SEQ+5))<br />
done<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
peer-up)<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -p daemon.err "GRE mapping of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU table nhrp_mtu<br />
fi<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42 table nhrp_mtu<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</pre><br />
<br />
== BGP ==<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
password zebra<br />
enable password zebra<br />
log syslog<br />
<br />
router bgp 65000<br />
bgp router-id %Hub2_GRE_IP%<br />
bgp deterministic-med<br />
network %GRE_NETWORK%/%MASK_BITS%<br />
neighbor hub peer-group<br />
neighbor hub next-hop-self<br />
neighbor hub route-map CORE-IN in<br />
neighbor spoke peer-group<br />
neighbor spoke passive<br />
neighbor spoke next-hop-self<br />
neighbor %Spoke1_GRE_IP% remote-as 65001<br />
neighbor %Spoke1_GRE_IP% peer-group spoke<br />
neighbor %Spoke1_GRE_IP% prefix-list net-65001-in in<br />
...<br />
...<br />
...<br />
<br />
neighbor hub remote-as 65000<br />
neighbor %Hub1_GRE_IP% peer-group core<br />
<br />
ip prefix-list net-65001-in seq 5 permit 10.1.0.0/16 le 26<br />
...<br />
<br />
route-map CORE-IN permit 10<br />
set metric +100<br />
</pre><br />
<br />
Add the lines <code>neighbor %Spoke1_GRE_IP%...</code> for each spoke node you have. Do the same on Hub 1, changing the relevant data for Hub 2.<br />
<br />
= Troubleshooting the DMVPN =<br />
== Broken [http://en.wikipedia.org/wiki/Path_MTU_Discovery Path MTU Discovery (PMTUD)] ==<br />
ISPs afraid of ICMP (which is somehow legitimate) just blindly add <code>no ip unreachables</code> in their router interfaces, effectively creating a [http://en.wikipedia.org/wiki/Black_hole_%28networking%29 blackhole router] that breaks PMTUD, since ICMP Type 3 Code 4 packets (Fragmentation Needed) are dropped. PMTUD is needed by ISAKMP that runs on UDP (TCP works because it uses CLAMPMSS).<br />
<br />
For technical details see http://packetlife.net/blog/2008/oct/9/disabling-unreachables-breaks-pmtud/<br />
<br />
PMTUD could also be broken due to badly configured DSL modem/routers or bugged firmware.<br />
<br />
You can easily detect which host is the blackhole router by pinging with DF bit set and with packets of standard MTU size, each hop given in your traceroute to destination:<br />
<br />
{{Cmd|ping -M do -s 1472 %IP%}}<br />
{{Note|"-M do" requires GNU ping, present in <code>iputils</code> package}}<br />
<br />
If you don't get a response back (either Echo-Response or Fragmentation-Needed) there's firewall dropping ICMP packets. If it answers to normal ping packets (DF bit cleared), most likely you have hit a blackhole router.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9323
Dynamic Multipoint VPN (DMVPN)
2013-08-23T15:18:27Z
<p>Jbilyk: /* Recursive DNS */</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Extract Certificates =<br />
We will use certificates for DMVPN and for OpenVPN (RoadWarrior clients). Here are the general purpose instruction for extracting certificates from pfx files:<br />
<br />
{{Cmd|openssl pkcs12 -in cert.pfx -cacerts -nokeys -out cacert.pem<br />
openssl pkcs12 -in cert.pfx -nocerts -nodes -out serverkey.pem<br />
openssl pkcs12 -in cert.pfx -nokeys -clcerts -out cert.pem<br />
}}<br />
<br />
Remember to set appropriate permission for your certificate files:<br />
<br />
{{Cmd|chmod 600 *.pem *.pfx}}<br />
<br />
= Spoke Node =<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Physically install ==<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to eth0. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== SSH ==<br />
Remove password authentication and DNS reverse lookup:<br />
{{Cmd|sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add -U unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Start unbound:<br />
<br />
{{Cmd|/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
<br />
<pre><br />
auto bond0.8<br />
...<br />
...<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
</pre><br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
nsdc rebuild<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor create <code>/etc/ipsec.conf</code> and set the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
{{Cmd|mkdir /etc/racoon/}}<br />
<br />
Extract your pfx into /etc/racoon, using the filenames '''ca.pem''', '''cert.pem''', and '''key.pem'''.<br />
<br />
With your favorite editor create <code>/etc/racoon/racoon.conf</code> and set the content to the following:<br />
<br />
<pre><br />
path certificate "/etc/racoon/";<br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Edit /etc/conf.d/racoon and unset RACOON_PSK_FILE:<br />
<br />
<pre><br />
...<br />
RACOON_PSK_FILE=<br />
...<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start<br />
rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=$(sed -n 's/router bgp \(\d*\)/\1/p' < /etc/quagga/bgpd.conf)<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script<br />
/etc/init.d/opennhrp start<br />
rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga<br />
touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start<br />
rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
{{Cmd|echo tun >> /etc/modules<br />
modprobe tun<br />
apk add openvpn<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start<br />
rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/clampmss.json'''</code><br />
<pre><br />
{<br />
"description": "Deal with ISPs afraid of ICMP",<br />
<br />
"import": "internet-host",<br />
<br />
"clamp-mss": [ { "out": "E" } ]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall enable clampmss<br />
awall enable vpnc<br />
awall activate<br />
rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu<br />
echo -e "1\tisp1">> /etc/iproute2/rt_tables<br />
echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
fwmark 1<br />
rule-priority 20000<br />
# google dns<br />
ping 8.8.8.8<br />
# opendns<br />
ping 208.67.222.222<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
fwmark 2<br />
rule-priority 20000<br />
}<br />
<br />
</pre><br />
<br />
Make sure we can reach the public IP from our LAN by adding static route rules for our private net(s). Edit <code>/etc/pingu/route-rules</code>:<br />
<pre><br />
to 10.0.0.0/8 table main prio 1000<br />
to 172.16.0.0/12 table main prio 1000<br />
</pre><br />
<br />
Start pingu:<br />
{{Cmd|/etc/init.d/pingu start<br />
rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
We will document only what changes from the Spoke node setup.<br />
<br />
== Routing Tables ==<br />
{{Cmd|echo -e "42\tnhrp_shortcut\n43\tnhrp_mtu\n44\tquagga\n}}<br />
<br />
== NHRP ==<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
interface gre1<br />
map %Hub1_GRE_IP%/%MaskBit% hub1.example.org<br />
route-table 44<br />
shortcut<br />
redirect<br />
non-caching<br />
</pre><br />
Do the same on Hub 1 adding the data relative to Hub 2.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and set the content as follows:<br />
<pre><br />
#!/bin/sh<br />
<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -t opennhrp-script -p auth.err "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
logger -t opennhrp-script -p auth.info "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA authenticated"<br />
<br />
(<br />
flock -x 200<br />
<br />
AS=`echo "$CERT" | grep "^AS=" | cut -b 4-`<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "router bgp 65000" \<br />
-c "neighbor $NHRP_DESTADDR remote-as $AS" \<br />
-c "neighbor $NHRP_DESTADDR peer-group leaf" \<br />
-c "neighbor $NHRP_DESTADDR prefix-list net-$AS-in in"<br />
<br />
SEQ=5<br />
(echo "$CERT" | grep "^NET=" | cut -b 5-) | while read NET; do<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "ip prefix-list net-$AS-in seq $SEQ permit $NET le 26"<br />
SEQ=$(($SEQ+5))<br />
done<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
peer-up)<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -p daemon.err "GRE mapping of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU table nhrp_mtu<br />
fi<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42 table nhrp_mtu<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</pre><br />
<br />
== BGP ==<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
password zebra<br />
enable password zebra<br />
log syslog<br />
<br />
router bgp 65000<br />
bgp router-id %Hub2_GRE_IP%<br />
bgp deterministic-med<br />
network %GRE_NETWORK%/%MASK_BITS%<br />
neighbor hub peer-group<br />
neighbor hub next-hop-self<br />
neighbor hub route-map CORE-IN in<br />
neighbor spoke peer-group<br />
neighbor spoke passive<br />
neighbor spoke next-hop-self<br />
neighbor %Spoke1_GRE_IP% remote-as 65001<br />
neighbor %Spoke1_GRE_IP% peer-group spoke<br />
neighbor %Spoke1_GRE_IP% prefix-list net-65001-in in<br />
...<br />
...<br />
...<br />
<br />
neighbor hub remote-as 65000<br />
neighbor %Hub1_GRE_IP% peer-group core<br />
<br />
ip prefix-list net-65001-in seq 5 permit 10.1.0.0/16 le 26<br />
...<br />
<br />
route-map CORE-IN permit 10<br />
set metric +100<br />
</pre><br />
<br />
Add the lines <code>neighbor %Spoke1_GRE_IP%...</code> for each spoke node you have. Do the same on Hub 1, changing the relevant data for Hub 2.<br />
<br />
= Troubleshooting the DMVPN =<br />
== Broken [http://en.wikipedia.org/wiki/Path_MTU_Discovery Path MTU Discovery (PMTUD)] ==<br />
ISPs afraid of ICMP (which is somehow legitimate) just blindly add <code>no ip unreachables</code> in their router interfaces, effectively creating a [http://en.wikipedia.org/wiki/Black_hole_%28networking%29 blackhole router] that breaks PMTUD, since ICMP Type 3 Code 4 packets (Fragmentation Needed) are dropped. PMTUD is needed by ISAKMP that runs on UDP (TCP works because it uses CLAMPMSS).<br />
<br />
For technical details see http://packetlife.net/blog/2008/oct/9/disabling-unreachables-breaks-pmtud/<br />
<br />
PMTUD could also be broken due to badly configured DSL modem/routers or bugged firmware.<br />
<br />
You can easily detect which host is the blackhole router by pinging with DF bit set and with packets of standard MTU size, each hop given in your traceroute to destination:<br />
<br />
{{Cmd|ping -M do -s 1472 %IP%}}<br />
{{Note|"-M do" requires GNU ping, present in <code>iputils</code> package}}<br />
<br />
If you don't get a response back (either Echo-Response or Fragmentation-Needed) there's firewall dropping ICMP packets. If it answers to normal ping packets (DF bit cleared), most likely you have hit a blackhole router.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9322
Dynamic Multipoint VPN (DMVPN)
2013-08-23T14:57:32Z
<p>Jbilyk: /* IPSEC */ add cert path</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Extract Certificates =<br />
We will use certificates for DMVPN and for OpenVPN (RoadWarrior clients). Here are the general purpose instruction for extracting certificates from pfx files:<br />
<br />
{{Cmd|openssl pkcs12 -in cert.pfx -cacerts -nokeys -out cacert.pem<br />
openssl pkcs12 -in cert.pfx -nocerts -nodes -out serverkey.pem<br />
openssl pkcs12 -in cert.pfx -nokeys -clcerts -out cert.pem<br />
}}<br />
<br />
Remember to set appropriate permission for your certificate files:<br />
<br />
{{Cmd|chmod 600 *.pem *.pfx}}<br />
<br />
= Spoke Node =<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Physically install ==<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to eth0. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== SSH ==<br />
Remove password authentication and DNS reverse lookup:<br />
{{Cmd|sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add -U unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/root.hints<br />
/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
<br />
<pre><br />
auto bond0.8<br />
...<br />
...<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
</pre><br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
nsdc rebuild<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor create <code>/etc/ipsec.conf</code> and set the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
{{Cmd|mkdir /etc/racoon/}}<br />
<br />
Extract your pfx into /etc/racoon, using the filenames '''ca.pem''', '''cert.pem''', and '''key.pem'''.<br />
<br />
With your favorite editor create <code>/etc/racoon/racoon.conf</code> and set the content to the following:<br />
<br />
<pre><br />
path certificate "/etc/racoon/";<br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Edit /etc/conf.d/racoon and unset RACOON_PSK_FILE:<br />
<br />
<pre><br />
...<br />
RACOON_PSK_FILE=<br />
...<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start<br />
rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=$(sed -n 's/router bgp \(\d*\)/\1/p' < /etc/quagga/bgpd.conf)<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script<br />
/etc/init.d/opennhrp start<br />
rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga<br />
touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start<br />
rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
{{Cmd|echo tun >> /etc/modules<br />
modprobe tun<br />
apk add openvpn<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start<br />
rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/clampmss.json'''</code><br />
<pre><br />
{<br />
"description": "Deal with ISPs afraid of ICMP",<br />
<br />
"import": "internet-host",<br />
<br />
"clamp-mss": [ { "out": "E" } ]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall enable clampmss<br />
awall enable vpnc<br />
awall activate<br />
rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu<br />
echo -e "1\tisp1">> /etc/iproute2/rt_tables<br />
echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
fwmark 1<br />
rule-priority 20000<br />
# google dns<br />
ping 8.8.8.8<br />
# opendns<br />
ping 208.67.222.222<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
fwmark 2<br />
rule-priority 20000<br />
}<br />
<br />
</pre><br />
<br />
Make sure we can reach the public IP from our LAN by adding static route rules for our private net(s). Edit <code>/etc/pingu/route-rules</code>:<br />
<pre><br />
to 10.0.0.0/8 table main prio 1000<br />
to 172.16.0.0/12 table main prio 1000<br />
</pre><br />
<br />
Start pingu:<br />
{{Cmd|/etc/init.d/pingu start<br />
rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
We will document only what changes from the Spoke node setup.<br />
<br />
== Routing Tables ==<br />
{{Cmd|echo -e "42\tnhrp_shortcut\n43\tnhrp_mtu\n44\tquagga\n}}<br />
<br />
== NHRP ==<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
interface gre1<br />
map %Hub1_GRE_IP%/%MaskBit% hub1.example.org<br />
route-table 44<br />
shortcut<br />
redirect<br />
non-caching<br />
</pre><br />
Do the same on Hub 1 adding the data relative to Hub 2.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and set the content as follows:<br />
<pre><br />
#!/bin/sh<br />
<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -t opennhrp-script -p auth.err "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
logger -t opennhrp-script -p auth.info "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA authenticated"<br />
<br />
(<br />
flock -x 200<br />
<br />
AS=`echo "$CERT" | grep "^AS=" | cut -b 4-`<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "router bgp 65000" \<br />
-c "neighbor $NHRP_DESTADDR remote-as $AS" \<br />
-c "neighbor $NHRP_DESTADDR peer-group leaf" \<br />
-c "neighbor $NHRP_DESTADDR prefix-list net-$AS-in in"<br />
<br />
SEQ=5<br />
(echo "$CERT" | grep "^NET=" | cut -b 5-) | while read NET; do<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "ip prefix-list net-$AS-in seq $SEQ permit $NET le 26"<br />
SEQ=$(($SEQ+5))<br />
done<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
peer-up)<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -p daemon.err "GRE mapping of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU table nhrp_mtu<br />
fi<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42 table nhrp_mtu<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</pre><br />
<br />
== BGP ==<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
password zebra<br />
enable password zebra<br />
log syslog<br />
<br />
router bgp 65000<br />
bgp router-id %Hub2_GRE_IP%<br />
bgp deterministic-med<br />
network %GRE_NETWORK%/%MASK_BITS%<br />
neighbor hub peer-group<br />
neighbor hub next-hop-self<br />
neighbor hub route-map CORE-IN in<br />
neighbor spoke peer-group<br />
neighbor spoke passive<br />
neighbor spoke next-hop-self<br />
neighbor %Spoke1_GRE_IP% remote-as 65001<br />
neighbor %Spoke1_GRE_IP% peer-group spoke<br />
neighbor %Spoke1_GRE_IP% prefix-list net-65001-in in<br />
...<br />
...<br />
...<br />
<br />
neighbor hub remote-as 65000<br />
neighbor %Hub1_GRE_IP% peer-group core<br />
<br />
ip prefix-list net-65001-in seq 5 permit 10.1.0.0/16 le 26<br />
...<br />
<br />
route-map CORE-IN permit 10<br />
set metric +100<br />
</pre><br />
<br />
Add the lines <code>neighbor %Spoke1_GRE_IP%...</code> for each spoke node you have. Do the same on Hub 1, changing the relevant data for Hub 2.<br />
<br />
= Troubleshooting the DMVPN =<br />
== Broken [http://en.wikipedia.org/wiki/Path_MTU_Discovery Path MTU Discovery (PMTUD)] ==<br />
ISPs afraid of ICMP (which is somehow legitimate) just blindly add <code>no ip unreachables</code> in their router interfaces, effectively creating a [http://en.wikipedia.org/wiki/Black_hole_%28networking%29 blackhole router] that breaks PMTUD, since ICMP Type 3 Code 4 packets (Fragmentation Needed) are dropped. PMTUD is needed by ISAKMP that runs on UDP (TCP works because it uses CLAMPMSS).<br />
<br />
For technical details see http://packetlife.net/blog/2008/oct/9/disabling-unreachables-breaks-pmtud/<br />
<br />
PMTUD could also be broken due to badly configured DSL modem/routers or bugged firmware.<br />
<br />
You can easily detect which host is the blackhole router by pinging with DF bit set and with packets of standard MTU size, each hop given in your traceroute to destination:<br />
<br />
{{Cmd|ping -M do -s 1472 %IP%}}<br />
{{Note|"-M do" requires GNU ping, present in <code>iputils</code> package}}<br />
<br />
If you don't get a response back (either Echo-Response or Fragmentation-Needed) there's firewall dropping ICMP packets. If it answers to normal ping packets (DF bit cleared), most likely you have hit a blackhole router.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9321
Dynamic Multipoint VPN (DMVPN)
2013-08-23T14:34:33Z
<p>Jbilyk: /* IPSEC */ cert component names</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Extract Certificates =<br />
We will use certificates for DMVPN and for OpenVPN (RoadWarrior clients). Here are the general purpose instruction for extracting certificates from pfx files:<br />
<br />
{{Cmd|openssl pkcs12 -in cert.pfx -cacerts -nokeys -out cacert.pem<br />
openssl pkcs12 -in cert.pfx -nocerts -nodes -out serverkey.pem<br />
openssl pkcs12 -in cert.pfx -nokeys -clcerts -out cert.pem<br />
}}<br />
<br />
Remember to set appropriate permission for your certificate files:<br />
<br />
{{Cmd|chmod 600 *.pem *.pfx}}<br />
<br />
= Spoke Node =<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Physically install ==<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to eth0. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== SSH ==<br />
Remove password authentication and DNS reverse lookup:<br />
{{Cmd|sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add -U unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/root.hints<br />
/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
<br />
<pre><br />
auto bond0.8<br />
...<br />
...<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
</pre><br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
nsdc rebuild<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor create <code>/etc/ipsec.conf</code> and set the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
{{Cmd|mkdir /etc/racoon/}}<br />
<br />
Extract your pfx into /etc/racoon, using the filenames '''ca.pem''', '''cert.pem''', and '''key.pem'''.<br />
<br />
With your favorite editor create <code>/etc/racoon/racoon.conf</code> and set the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Edit /etc/conf.d/racoon and unset RACOON_PSK_FILE:<br />
<br />
<pre><br />
...<br />
RACOON_PSK_FILE=<br />
...<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start<br />
rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=$(sed -n 's/router bgp \(\d*\)/\1/p' < /etc/quagga/bgpd.conf)<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script<br />
/etc/init.d/opennhrp start<br />
rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga<br />
touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start<br />
rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
{{Cmd|echo tun >> /etc/modules<br />
modprobe tun<br />
apk add openvpn<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start<br />
rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/clampmss.json'''</code><br />
<pre><br />
{<br />
"description": "Deal with ISPs afraid of ICMP",<br />
<br />
"import": "internet-host",<br />
<br />
"clamp-mss": [ { "out": "E" } ]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall enable clampmss<br />
awall enable vpnc<br />
awall activate<br />
rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu<br />
echo -e "1\tisp1">> /etc/iproute2/rt_tables<br />
echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
fwmark 1<br />
rule-priority 20000<br />
# google dns<br />
ping 8.8.8.8<br />
# opendns<br />
ping 208.67.222.222<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
fwmark 2<br />
rule-priority 20000<br />
}<br />
<br />
</pre><br />
<br />
Make sure we can reach the public IP from our LAN by adding static route rules for our private net(s). Edit <code>/etc/pingu/route-rules</code>:<br />
<pre><br />
to 10.0.0.0/8 table main prio 1000<br />
to 172.16.0.0/12 table main prio 1000<br />
</pre><br />
<br />
Start pingu:<br />
{{Cmd|/etc/init.d/pingu start<br />
rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
We will document only what changes from the Spoke node setup.<br />
<br />
== Routing Tables ==<br />
{{Cmd|echo -e "42\tnhrp_shortcut\n43\tnhrp_mtu\n44\tquagga\n}}<br />
<br />
== NHRP ==<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
interface gre1<br />
map %Hub1_GRE_IP%/%MaskBit% hub1.example.org<br />
route-table 44<br />
shortcut<br />
redirect<br />
non-caching<br />
</pre><br />
Do the same on Hub 1 adding the data relative to Hub 2.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and set the content as follows:<br />
<pre><br />
#!/bin/sh<br />
<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -t opennhrp-script -p auth.err "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
logger -t opennhrp-script -p auth.info "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA authenticated"<br />
<br />
(<br />
flock -x 200<br />
<br />
AS=`echo "$CERT" | grep "^AS=" | cut -b 4-`<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "router bgp 65000" \<br />
-c "neighbor $NHRP_DESTADDR remote-as $AS" \<br />
-c "neighbor $NHRP_DESTADDR peer-group leaf" \<br />
-c "neighbor $NHRP_DESTADDR prefix-list net-$AS-in in"<br />
<br />
SEQ=5<br />
(echo "$CERT" | grep "^NET=" | cut -b 5-) | while read NET; do<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "ip prefix-list net-$AS-in seq $SEQ permit $NET le 26"<br />
SEQ=$(($SEQ+5))<br />
done<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
peer-up)<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -p daemon.err "GRE mapping of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU table nhrp_mtu<br />
fi<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42 table nhrp_mtu<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</pre><br />
<br />
== BGP ==<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
password zebra<br />
enable password zebra<br />
log syslog<br />
<br />
router bgp 65000<br />
bgp router-id %Hub2_GRE_IP%<br />
bgp deterministic-med<br />
network %GRE_NETWORK%/%MASK_BITS%<br />
neighbor hub peer-group<br />
neighbor hub next-hop-self<br />
neighbor hub route-map CORE-IN in<br />
neighbor spoke peer-group<br />
neighbor spoke passive<br />
neighbor spoke next-hop-self<br />
neighbor %Spoke1_GRE_IP% remote-as 65001<br />
neighbor %Spoke1_GRE_IP% peer-group spoke<br />
neighbor %Spoke1_GRE_IP% prefix-list net-65001-in in<br />
...<br />
...<br />
...<br />
<br />
neighbor hub remote-as 65000<br />
neighbor %Hub1_GRE_IP% peer-group core<br />
<br />
ip prefix-list net-65001-in seq 5 permit 10.1.0.0/16 le 26<br />
...<br />
<br />
route-map CORE-IN permit 10<br />
set metric +100<br />
</pre><br />
<br />
Add the lines <code>neighbor %Spoke1_GRE_IP%...</code> for each spoke node you have. Do the same on Hub 1, changing the relevant data for Hub 2.<br />
<br />
= Troubleshooting the DMVPN =<br />
== Broken [http://en.wikipedia.org/wiki/Path_MTU_Discovery Path MTU Discovery (PMTUD)] ==<br />
ISPs afraid of ICMP (which is somehow legitimate) just blindly add <code>no ip unreachables</code> in their router interfaces, effectively creating a [http://en.wikipedia.org/wiki/Black_hole_%28networking%29 blackhole router] that breaks PMTUD, since ICMP Type 3 Code 4 packets (Fragmentation Needed) are dropped. PMTUD is needed by ISAKMP that runs on UDP (TCP works because it uses CLAMPMSS).<br />
<br />
For technical details see http://packetlife.net/blog/2008/oct/9/disabling-unreachables-breaks-pmtud/<br />
<br />
PMTUD could also be broken due to badly configured DSL modem/routers or bugged firmware.<br />
<br />
You can easily detect which host is the blackhole router by pinging with DF bit set and with packets of standard MTU size, each hop given in your traceroute to destination:<br />
<br />
{{Cmd|ping -M do -s 1472 %IP%}}<br />
{{Note|"-M do" requires GNU ping, present in <code>iputils</code> package}}<br />
<br />
If you don't get a response back (either Echo-Response or Fragmentation-Needed) there's firewall dropping ICMP packets. If it answers to normal ping packets (DF bit cleared), most likely you have hit a blackhole router.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9320
Dynamic Multipoint VPN (DMVPN)
2013-08-23T14:22:04Z
<p>Jbilyk: /* IPSEC */</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Extract Certificates =<br />
We will use certificates for DMVPN and for OpenVPN (RoadWarrior clients). Here are the general purpose instruction for extracting certificates from pfx files:<br />
<br />
{{Cmd|openssl pkcs12 -in cert.pfx -cacerts -nokeys -out cacert.pem<br />
openssl pkcs12 -in cert.pfx -nocerts -nodes -out serverkey.pem<br />
openssl pkcs12 -in cert.pfx -nokeys -clcerts -out cert.pem<br />
}}<br />
<br />
Remember to set appropriate permission for your certificate files:<br />
<br />
{{Cmd|chmod 600 *.pem *.pfx}}<br />
<br />
= Spoke Node =<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Physically install ==<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to eth0. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== SSH ==<br />
Remove password authentication and DNS reverse lookup:<br />
{{Cmd|sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config<br />
sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config}}<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add -U unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/root.hints<br />
/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
<br />
<pre><br />
auto bond0.8<br />
...<br />
...<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
</pre><br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
nsdc rebuild<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor create <code>/etc/ipsec.conf</code> and set the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
{{Cmd|mkdir /etc/racoon/}}<br />
<br />
With your favorite editor create <code>/etc/racoon/racoon.conf</code> and set the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Edit /etc/conf.d/racoon and unset RACOON_PSK_FILE:<br />
<br />
<pre><br />
...<br />
RACOON_PSK_FILE=<br />
...<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start<br />
rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=$(sed -n 's/router bgp \(\d*\)/\1/p' < /etc/quagga/bgpd.conf)<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script<br />
/etc/init.d/opennhrp start<br />
rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga<br />
touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start<br />
rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
{{Cmd|echo tun >> /etc/modules<br />
modprobe tun<br />
apk add openvpn<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start<br />
rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/clampmss.json'''</code><br />
<pre><br />
{<br />
"description": "Deal with ISPs afraid of ICMP",<br />
<br />
"import": "internet-host",<br />
<br />
"clamp-mss": [ { "out": "E" } ]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall enable clampmss<br />
awall enable vpnc<br />
awall activate<br />
rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu<br />
echo -e "1\tisp1">> /etc/iproute2/rt_tables<br />
echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
fwmark 1<br />
rule-priority 20000<br />
# google dns<br />
ping 8.8.8.8<br />
# opendns<br />
ping 208.67.222.222<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
fwmark 2<br />
rule-priority 20000<br />
}<br />
<br />
</pre><br />
<br />
Make sure we can reach the public IP from our LAN by adding static route rules for our private net(s). Edit <code>/etc/pingu/route-rules</code>:<br />
<pre><br />
to 10.0.0.0/8 table main prio 1000<br />
to 172.16.0.0/12 table main prio 1000<br />
</pre><br />
<br />
Start pingu:<br />
{{Cmd|/etc/init.d/pingu start<br />
rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
We will document only what changes from the Spoke node setup.<br />
<br />
== Routing Tables ==<br />
{{Cmd|echo -e "42\tnhrp_shortcut\n43\tnhrp_mtu\n44\tquagga\n}}<br />
<br />
== NHRP ==<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
interface gre1<br />
map %Hub1_GRE_IP%/%MaskBit% hub1.example.org<br />
route-table 44<br />
shortcut<br />
redirect<br />
non-caching<br />
</pre><br />
Do the same on Hub 1 adding the data relative to Hub 2.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and set the content as follows:<br />
<pre><br />
#!/bin/sh<br />
<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -t opennhrp-script -p auth.err "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
logger -t opennhrp-script -p auth.info "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA authenticated"<br />
<br />
(<br />
flock -x 200<br />
<br />
AS=`echo "$CERT" | grep "^AS=" | cut -b 4-`<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "router bgp 65000" \<br />
-c "neighbor $NHRP_DESTADDR remote-as $AS" \<br />
-c "neighbor $NHRP_DESTADDR peer-group leaf" \<br />
-c "neighbor $NHRP_DESTADDR prefix-list net-$AS-in in"<br />
<br />
SEQ=5<br />
(echo "$CERT" | grep "^NET=" | cut -b 5-) | while read NET; do<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "ip prefix-list net-$AS-in seq $SEQ permit $NET le 26"<br />
SEQ=$(($SEQ+5))<br />
done<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
peer-up)<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -p daemon.err "GRE mapping of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU table nhrp_mtu<br />
fi<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42 table nhrp_mtu<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</pre><br />
<br />
== BGP ==<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
password zebra<br />
enable password zebra<br />
log syslog<br />
<br />
router bgp 65000<br />
bgp router-id %Hub2_GRE_IP%<br />
bgp deterministic-med<br />
network %GRE_NETWORK%/%MASK_BITS%<br />
neighbor hub peer-group<br />
neighbor hub next-hop-self<br />
neighbor hub route-map CORE-IN in<br />
neighbor spoke peer-group<br />
neighbor spoke passive<br />
neighbor spoke next-hop-self<br />
neighbor %Spoke1_GRE_IP% remote-as 65001<br />
neighbor %Spoke1_GRE_IP% peer-group spoke<br />
neighbor %Spoke1_GRE_IP% prefix-list net-65001-in in<br />
...<br />
...<br />
...<br />
<br />
neighbor hub remote-as 65000<br />
neighbor %Hub1_GRE_IP% peer-group core<br />
<br />
ip prefix-list net-65001-in seq 5 permit 10.1.0.0/16 le 26<br />
...<br />
<br />
route-map CORE-IN permit 10<br />
set metric +100<br />
</pre><br />
<br />
Add the lines <code>neighbor %Spoke1_GRE_IP%...</code> for each spoke node you have. Do the same on Hub 1, changing the relevant data for Hub 2.<br />
<br />
= Troubleshooting the DMVPN =<br />
== Broken [http://en.wikipedia.org/wiki/Path_MTU_Discovery Path MTU Discovery (PMTUD)] ==<br />
ISPs afraid of ICMP (which is somehow legitimate) just blindly add <code>no ip unreachables</code> in their router interfaces, effectively creating a [http://en.wikipedia.org/wiki/Black_hole_%28networking%29 blackhole router] that breaks PMTUD, since ICMP Type 3 Code 4 packets (Fragmentation Needed) are dropped. PMTUD is needed by ISAKMP that runs on UDP (TCP works because it uses CLAMPMSS).<br />
<br />
For technical details see http://packetlife.net/blog/2008/oct/9/disabling-unreachables-breaks-pmtud/<br />
<br />
PMTUD could also be broken due to badly configured DSL modem/routers or bugged firmware.<br />
<br />
You can easily detect which host is the blackhole router by pinging with DF bit set and with packets of standard MTU size, each hop given in your traceroute to destination:<br />
<br />
{{Cmd|ping -M do -s 1472 %IP%}}<br />
{{Note|"-M do" requires GNU ping, present in <code>iputils</code> package}}<br />
<br />
If you don't get a response back (either Echo-Response or Fragmentation-Needed) there's firewall dropping ICMP packets. If it answers to normal ping packets (DF bit cleared), most likely you have hit a blackhole router.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9317
Dynamic Multipoint VPN (DMVPN)
2013-08-23T14:16:47Z
<p>Jbilyk: create racoon folder</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Extract Certificates =<br />
We will use certificates for DMVPN and for OpenVPN (RoadWarrior clients). Here are the general purpose instruction for extracting certificates from pfx files:<br />
<br />
{{Cmd|openssl pkcs12 -in cert.pfx -cacerts -nokeys -out cacert.pem<br />
openssl pkcs12 -in cert.pfx -nocerts -nodes -out serverkey.pem<br />
openssl pkcs12 -in cert.pfx -nokeys -clcerts -out cert.pem<br />
}}<br />
<br />
Remember to set appropriate permission for your certificate files:<br />
<br />
{{Cmd|chmod 600 *.pem *.pfx}}<br />
<br />
= Spoke Node =<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Physically install ==<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to eth0. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== SSH ==<br />
Remove password authentication<br />
{{Cmd|sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config}}<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add -U unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/root.hints<br />
/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
<br />
<pre><br />
auto bond0.8<br />
...<br />
...<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
</pre><br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
nsdc rebuild<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor create <code>/etc/ipsec.conf</code> and set the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
{{Cmd|mkdir /etc/racoon/}}<br />
<br />
With your favorite editor create <code>/etc/racoon/racoon.conf</code> and set the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start<br />
rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=$(sed -n 's/router bgp \(\d*\)/\1/p' < /etc/quagga/bgpd.conf)<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script<br />
/etc/init.d/opennhrp start<br />
rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga<br />
touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start<br />
rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
{{Cmd|echo tun >> /etc/modules<br />
modprobe tun<br />
apk add openvpn<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start<br />
rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/clampmss.json'''</code><br />
<pre><br />
{<br />
"description": "Deal with ISPs afraid of ICMP",<br />
<br />
"import": "internet-host",<br />
<br />
"clamp-mss": [ { "out": "E" } ]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall enable clampmss<br />
awall enable vpnc<br />
awall activate<br />
rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu<br />
echo -e "1\tisp1">> /etc/iproute2/rt_tables<br />
echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
fwmark 1<br />
rule-priority 20000<br />
# google dns<br />
ping 8.8.8.8<br />
# opendns<br />
ping 208.67.222.222<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
fwmark 2<br />
rule-priority 20000<br />
}<br />
<br />
</pre><br />
<br />
Make sure we can reach the public IP from our LAN by adding static route rules for our private net(s). Edit <code>/etc/pingu/route-rules</code>:<br />
<pre><br />
to 10.0.0.0/8 table main prio 1000<br />
to 172.16.0.0/12 table main prio 1000<br />
</pre><br />
<br />
Start pingu:<br />
{{Cmd|/etc/init.d/pingu start<br />
rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
We will document only what changes from the Spoke node setup.<br />
<br />
== Routing Tables ==<br />
{{Cmd|echo -e "42\tnhrp_shortcut\n43\tnhrp_mtu\n44\tquagga\n}}<br />
<br />
== NHRP ==<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
interface gre1<br />
map %Hub1_GRE_IP%/%MaskBit% hub1.example.org<br />
route-table 44<br />
shortcut<br />
redirect<br />
non-caching<br />
</pre><br />
Do the same on Hub 1 adding the data relative to Hub 2.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and set the content as follows:<br />
<pre><br />
#!/bin/sh<br />
<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -t opennhrp-script -p auth.err "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
logger -t opennhrp-script -p auth.info "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA authenticated"<br />
<br />
(<br />
flock -x 200<br />
<br />
AS=`echo "$CERT" | grep "^AS=" | cut -b 4-`<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "router bgp 65000" \<br />
-c "neighbor $NHRP_DESTADDR remote-as $AS" \<br />
-c "neighbor $NHRP_DESTADDR peer-group leaf" \<br />
-c "neighbor $NHRP_DESTADDR prefix-list net-$AS-in in"<br />
<br />
SEQ=5<br />
(echo "$CERT" | grep "^NET=" | cut -b 5-) | while read NET; do<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "ip prefix-list net-$AS-in seq $SEQ permit $NET le 26"<br />
SEQ=$(($SEQ+5))<br />
done<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
peer-up)<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -p daemon.err "GRE mapping of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU table nhrp_mtu<br />
fi<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42 table nhrp_mtu<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</pre><br />
<br />
== BGP ==<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
password zebra<br />
enable password zebra<br />
log syslog<br />
<br />
router bgp 65000<br />
bgp router-id %Hub2_GRE_IP%<br />
bgp deterministic-med<br />
network %GRE_NETWORK%/%MASK_BITS%<br />
neighbor hub peer-group<br />
neighbor hub next-hop-self<br />
neighbor hub route-map CORE-IN in<br />
neighbor spoke peer-group<br />
neighbor spoke passive<br />
neighbor spoke next-hop-self<br />
neighbor %Spoke1_GRE_IP% remote-as 65001<br />
neighbor %Spoke1_GRE_IP% peer-group spoke<br />
neighbor %Spoke1_GRE_IP% prefix-list net-65001-in in<br />
...<br />
...<br />
...<br />
<br />
neighbor hub remote-as 65000<br />
neighbor %Hub1_GRE_IP% peer-group core<br />
<br />
ip prefix-list net-65001-in seq 5 permit 10.1.0.0/16 le 26<br />
...<br />
<br />
route-map CORE-IN permit 10<br />
set metric +100<br />
</pre><br />
<br />
Add the lines <code>neighbor %Spoke1_GRE_IP%...</code> for each spoke node you have. Do the same on Hub 1, changing the relevant data for Hub 2.<br />
<br />
= Troubleshooting the DMVPN =<br />
== Broken [http://en.wikipedia.org/wiki/Path_MTU_Discovery Path MTU Discovery (PMTUD)] ==<br />
ISPs afraid of ICMP (which is somehow legitimate) just blindly add <code>no ip unreachables</code> in their router interfaces, effectively creating a [http://en.wikipedia.org/wiki/Black_hole_%28networking%29 blackhole router] that breaks PMTUD, since ICMP Type 3 Code 4 packets (Fragmentation Needed) are dropped. PMTUD is needed by ISAKMP that runs on UDP (TCP works because it uses CLAMPMSS).<br />
<br />
For technical details see http://packetlife.net/blog/2008/oct/9/disabling-unreachables-breaks-pmtud/<br />
<br />
PMTUD could also be broken due to badly configured DSL modem/routers or bugged firmware.<br />
<br />
You can easily detect which host is the blackhole router by pinging with DF bit set and with packets of standard MTU size, each hop given in your traceroute to destination:<br />
<br />
{{Cmd|ping -M do -s 1472 %IP%}}<br />
{{Note|"-M do" requires GNU ping, present in <code>iputils</code> package}}<br />
<br />
If you don't get a response back (either Echo-Response or Fragmentation-Needed) there's firewall dropping ICMP packets. If it answers to normal ping packets (DF bit cleared), most likely you have hit a blackhole router.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9316
Dynamic Multipoint VPN (DMVPN)
2013-08-23T14:12:59Z
<p>Jbilyk: remove chrony - it's already done in setup-alpine</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Extract Certificates =<br />
We will use certificates for DMVPN and for OpenVPN (RoadWarrior clients). Here are the general purpose instruction for extracting certificates from pfx files:<br />
<br />
{{Cmd|openssl pkcs12 -in cert.pfx -cacerts -nokeys -out cacert.pem<br />
openssl pkcs12 -in cert.pfx -nocerts -nodes -out serverkey.pem<br />
openssl pkcs12 -in cert.pfx -nokeys -clcerts -out cert.pem<br />
}}<br />
<br />
Remember to set appropriate permission for your certificate files:<br />
<br />
{{Cmd|chmod 600 *.pem *.pfx}}<br />
<br />
= Spoke Node =<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Physically install ==<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to eth0. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== SSH ==<br />
Remove password authentication<br />
{{Cmd|sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config}}<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add -U unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/root.hints<br />
/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
<br />
<pre><br />
auto bond0.8<br />
...<br />
...<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
</pre><br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
nsdc rebuild<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start<br />
rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=$(sed -n 's/router bgp \(\d*\)/\1/p' < /etc/quagga/bgpd.conf)<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script<br />
/etc/init.d/opennhrp start<br />
rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga<br />
touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start<br />
rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
{{Cmd|echo tun >> /etc/modules<br />
modprobe tun<br />
apk add openvpn<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start<br />
rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/clampmss.json'''</code><br />
<pre><br />
{<br />
"description": "Deal with ISPs afraid of ICMP",<br />
<br />
"import": "internet-host",<br />
<br />
"clamp-mss": [ { "out": "E" } ]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall enable clampmss<br />
awall enable vpnc<br />
awall activate<br />
rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu<br />
echo -e "1\tisp1">> /etc/iproute2/rt_tables<br />
echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
fwmark 1<br />
rule-priority 20000<br />
# google dns<br />
ping 8.8.8.8<br />
# opendns<br />
ping 208.67.222.222<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
fwmark 2<br />
rule-priority 20000<br />
}<br />
<br />
</pre><br />
<br />
Make sure we can reach the public IP from our LAN by adding static route rules for our private net(s). Edit <code>/etc/pingu/route-rules</code>:<br />
<pre><br />
to 10.0.0.0/8 table main prio 1000<br />
to 172.16.0.0/12 table main prio 1000<br />
</pre><br />
<br />
Start pingu:<br />
{{Cmd|/etc/init.d/pingu start<br />
rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
We will document only what changes from the Spoke node setup.<br />
<br />
== Routing Tables ==<br />
{{Cmd|echo -e "42\tnhrp_shortcut\n43\tnhrp_mtu\n44\tquagga\n}}<br />
<br />
== NHRP ==<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
interface gre1<br />
map %Hub1_GRE_IP%/%MaskBit% hub1.example.org<br />
route-table 44<br />
shortcut<br />
redirect<br />
non-caching<br />
</pre><br />
Do the same on Hub 1 adding the data relative to Hub 2.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and set the content as follows:<br />
<pre><br />
#!/bin/sh<br />
<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -t opennhrp-script -p auth.err "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
logger -t opennhrp-script -p auth.info "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA authenticated"<br />
<br />
(<br />
flock -x 200<br />
<br />
AS=`echo "$CERT" | grep "^AS=" | cut -b 4-`<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "router bgp 65000" \<br />
-c "neighbor $NHRP_DESTADDR remote-as $AS" \<br />
-c "neighbor $NHRP_DESTADDR peer-group leaf" \<br />
-c "neighbor $NHRP_DESTADDR prefix-list net-$AS-in in"<br />
<br />
SEQ=5<br />
(echo "$CERT" | grep "^NET=" | cut -b 5-) | while read NET; do<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "ip prefix-list net-$AS-in seq $SEQ permit $NET le 26"<br />
SEQ=$(($SEQ+5))<br />
done<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
peer-up)<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -p daemon.err "GRE mapping of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU table nhrp_mtu<br />
fi<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42 table nhrp_mtu<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</pre><br />
<br />
== BGP ==<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
password zebra<br />
enable password zebra<br />
log syslog<br />
<br />
router bgp 65000<br />
bgp router-id %Hub2_GRE_IP%<br />
bgp deterministic-med<br />
network %GRE_NETWORK%/%MASK_BITS%<br />
neighbor hub peer-group<br />
neighbor hub next-hop-self<br />
neighbor hub route-map CORE-IN in<br />
neighbor spoke peer-group<br />
neighbor spoke passive<br />
neighbor spoke next-hop-self<br />
neighbor %Spoke1_GRE_IP% remote-as 65001<br />
neighbor %Spoke1_GRE_IP% peer-group spoke<br />
neighbor %Spoke1_GRE_IP% prefix-list net-65001-in in<br />
...<br />
...<br />
...<br />
<br />
neighbor hub remote-as 65000<br />
neighbor %Hub1_GRE_IP% peer-group core<br />
<br />
ip prefix-list net-65001-in seq 5 permit 10.1.0.0/16 le 26<br />
...<br />
<br />
route-map CORE-IN permit 10<br />
set metric +100<br />
</pre><br />
<br />
Add the lines <code>neighbor %Spoke1_GRE_IP%...</code> for each spoke node you have. Do the same on Hub 1, changing the relevant data for Hub 2.<br />
<br />
= Troubleshooting the DMVPN =<br />
== Broken [http://en.wikipedia.org/wiki/Path_MTU_Discovery Path MTU Discovery (PMTUD)] ==<br />
ISPs afraid of ICMP (which is somehow legitimate) just blindly add <code>no ip unreachables</code> in their router interfaces, effectively creating a [http://en.wikipedia.org/wiki/Black_hole_%28networking%29 blackhole router] that breaks PMTUD, since ICMP Type 3 Code 4 packets (Fragmentation Needed) are dropped. PMTUD is needed by ISAKMP that runs on UDP (TCP works because it uses CLAMPMSS).<br />
<br />
For technical details see http://packetlife.net/blog/2008/oct/9/disabling-unreachables-breaks-pmtud/<br />
<br />
PMTUD could also be broken due to badly configured DSL modem/routers or bugged firmware.<br />
<br />
You can easily detect which host is the blackhole router by pinging with DF bit set and with packets of standard MTU size, each hop given in your traceroute to destination:<br />
<br />
{{Cmd|ping -M do -s 1472 %IP%}}<br />
{{Note|"-M do" requires GNU ping, present in <code>iputils</code> package}}<br />
<br />
If you don't get a response back (either Echo-Response or Fragmentation-Needed) there's firewall dropping ICMP packets. If it answers to normal ping packets (DF bit cleared), most likely you have hit a blackhole router.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9314
Dynamic Multipoint VPN (DMVPN)
2013-08-23T14:08:46Z
<p>Jbilyk: add to update apk cache when installing unbound</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Extract Certificates =<br />
We will use certificates for DMVPN and for OpenVPN (RoadWarrior clients). Here are the general purpose instruction for extracting certificates from pfx files:<br />
<br />
{{Cmd|openssl pkcs12 -in cert.pfx -cacerts -nokeys -out cacert.pem<br />
openssl pkcs12 -in cert.pfx -nocerts -nodes -out serverkey.pem<br />
openssl pkcs12 -in cert.pfx -nokeys -clcerts -out cert.pem<br />
}}<br />
<br />
Remember to set appropriate permission for your certificate files:<br />
<br />
{{Cmd|chmod 600 *.pem *.pfx}}<br />
<br />
= Spoke Node =<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Physically install ==<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to eth0. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== SSH ==<br />
Remove password authentication<br />
{{Cmd|sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config}}<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add -U unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
<br />
do-not-query-localhost: no<br />
<br />
root-hints: "/etc/unbound/root.hints"<br />
<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
stub-zone:<br />
name: "example2.net"<br />
stub-addr: 172.16.255.1<br />
stub-addr: 172.16.255.2<br />
stub-addr: 172.16.255.3<br />
stub-addr: 172.16.255.4<br />
stub-addr: 172.16.255.5<br />
stub-addr: 172.16.255.7<br />
<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/named.cache<br />
/etc/init.d/unbound start<br />
rc-update add unbound<br />
echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
<br />
<pre><br />
auto bond0.8<br />
...<br />
...<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
</pre><br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf<br />
nsdc rebuild<br />
/etc/init.d/nsd start<br />
rc-update add nsd}}<br />
<br />
== NTP ==<br />
{{Cmd|apk add chrony<br />
/etc/init.d/chronyd start<br />
rc-update add chronyd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start<br />
rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=$(sed -n 's/router bgp \(\d*\)/\1/p' < /etc/quagga/bgpd.conf)<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script<br />
/etc/init.d/opennhrp start<br />
rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga<br />
touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start<br />
rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
{{Cmd|echo tun >> /etc/modules<br />
modprobe tun<br />
apk add openvpn<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start<br />
rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/clampmss.json'''</code><br />
<pre><br />
{<br />
"description": "Deal with ISPs afraid of ICMP",<br />
<br />
"import": "internet-host",<br />
<br />
"clamp-mss": [ { "out": "E" } ]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall enable clampmss<br />
awall enable vpnc<br />
awall activate<br />
rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu<br />
echo -e "1\tisp1">> /etc/iproute2/rt_tables<br />
echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
fwmark 1<br />
rule-priority 20000<br />
# google dns<br />
ping 8.8.8.8<br />
# opendns<br />
ping 208.67.222.222<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
fwmark 2<br />
rule-priority 20000<br />
}<br />
<br />
</pre><br />
<br />
Make sure we can reach the public IP from our LAN by adding static route rules for our private net(s). Edit <code>/etc/pingu/route-rules</code>:<br />
<pre><br />
to 10.0.0.0/8 table main prio 1000<br />
to 172.16.0.0/12 table main prio 1000<br />
</pre><br />
<br />
Start pingu:<br />
{{Cmd|/etc/init.d/pingu start<br />
rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
We will document only what changes from the Spoke node setup.<br />
<br />
== Routing Tables ==<br />
{{Cmd|echo -e "42\tnhrp_shortcut\n43\tnhrp_mtu\n44\tquagga\n}}<br />
<br />
== NHRP ==<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
interface gre1<br />
map %Hub1_GRE_IP%/%MaskBit% hub1.example.org<br />
route-table 44<br />
shortcut<br />
redirect<br />
non-caching<br />
</pre><br />
Do the same on Hub 1 adding the data relative to Hub 2.<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and set the content as follows:<br />
<pre><br />
#!/bin/sh<br />
<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -t opennhrp-script -p auth.err "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
logger -t opennhrp-script -p auth.info "GRE registration of $NHRP_DESTADDR to $NHRP_DESTNBMA authenticated"<br />
<br />
(<br />
flock -x 200<br />
<br />
AS=`echo "$CERT" | grep "^AS=" | cut -b 4-`<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "router bgp 65000" \<br />
-c "neighbor $NHRP_DESTADDR remote-as $AS" \<br />
-c "neighbor $NHRP_DESTADDR peer-group leaf" \<br />
-c "neighbor $NHRP_DESTADDR prefix-list net-$AS-in in"<br />
<br />
SEQ=5<br />
(echo "$CERT" | grep "^NET=" | cut -b 5-) | while read NET; do<br />
vtysh -d bgpd -c "configure terminal" \<br />
-c "ip prefix-list net-$AS-in seq $SEQ permit $NET le 26"<br />
SEQ=$(($SEQ+5))<br />
done<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
peer-up)<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
<br />
CERT=`racoonctl get-cert inet $NHRP_SRCNBMA $NHRP_DESTNBMA | openssl x509 -inform der -text -noout | egrep -o "/OU=[^/]*(/[0-9]+)?" | cut -b 5-`<br />
if [ -z "`echo "$CERT" | grep "^GRE=$NHRP_DESTADDR"`" ]; then<br />
logger -p daemon.err "GRE mapping of $NHRP_DESTADDR to $NHRP_DESTNBMA DENIED"<br />
exit 1<br />
fi<br />
<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU table nhrp_mtu<br />
fi<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42 table nhrp_mtu<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 table nhrp_shortcut<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
</pre><br />
<br />
== BGP ==<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> on Hub 2 and set the content as follows:<br />
<pre><br />
password zebra<br />
enable password zebra<br />
log syslog<br />
<br />
router bgp 65000<br />
bgp router-id %Hub2_GRE_IP%<br />
bgp deterministic-med<br />
network %GRE_NETWORK%/%MASK_BITS%<br />
neighbor hub peer-group<br />
neighbor hub next-hop-self<br />
neighbor hub route-map CORE-IN in<br />
neighbor spoke peer-group<br />
neighbor spoke passive<br />
neighbor spoke next-hop-self<br />
neighbor %Spoke1_GRE_IP% remote-as 65001<br />
neighbor %Spoke1_GRE_IP% peer-group spoke<br />
neighbor %Spoke1_GRE_IP% prefix-list net-65001-in in<br />
...<br />
...<br />
...<br />
<br />
neighbor hub remote-as 65000<br />
neighbor %Hub1_GRE_IP% peer-group core<br />
<br />
ip prefix-list net-65001-in seq 5 permit 10.1.0.0/16 le 26<br />
...<br />
<br />
route-map CORE-IN permit 10<br />
set metric +100<br />
</pre><br />
<br />
Add the lines <code>neighbor %Spoke1_GRE_IP%...</code> for each spoke node you have. Do the same on Hub 1, changing the relevant data for Hub 2.<br />
<br />
= Troubleshooting the DMVPN =<br />
== Broken [http://en.wikipedia.org/wiki/Path_MTU_Discovery Path MTU Discovery (PMTUD)] ==<br />
ISPs afraid of ICMP (which is somehow legitimate) just blindly add <code>no ip unreachables</code> in their router interfaces, effectively creating a [http://en.wikipedia.org/wiki/Black_hole_%28networking%29 blackhole router] that breaks PMTUD, since ICMP Type 3 Code 4 packets (Fragmentation Needed) are dropped. PMTUD is needed by ISAKMP that runs on UDP (TCP works because it uses CLAMPMSS).<br />
<br />
For technical details see http://packetlife.net/blog/2008/oct/9/disabling-unreachables-breaks-pmtud/<br />
<br />
PMTUD could also be broken due to badly configured DSL modem/routers or bugged firmware.<br />
<br />
You can easily detect which host is the blackhole router by pinging with DF bit set and with packets of standard MTU size, each hop given in your traceroute to destination:<br />
<br />
{{Cmd|ping -M do -s 1472 %IP%}}<br />
{{Note|"-M do" requires GNU ping, present in <code>iputils</code> package}}<br />
<br />
If you don't get a response back (either Echo-Response or Fragmentation-Needed) there's firewall dropping ICMP packets. If it answers to normal ping packets (DF bit cleared), most likely you have hit a blackhole router.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9274
Dynamic Multipoint VPN (DMVPN)
2013-08-21T12:46:05Z
<p>Jbilyk: physical install</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Spoke Node =<br />
<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Physically install ==<br />
<br />
At this point, you're ready to connect the VPN Spoke Node to the network if you haven't already done so. Please set up an 802.1q capable switch with the VLANs listed in AlpineSetup section. Once done, tag all of the VLANs on one port. Connect that port to eth0. Then, connect your first ISP's CPE to a switchport with VLAN 256 untagged.<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
do-not-query-localhost: no<br />
root-hints: "/etc/unbound/named.cache"<br />
forward-zone:<br />
name: "example.net"<br />
forward-addr: 172.16.255.1<br />
forward-addr: 172.16.255.2<br />
forward-addr: 172.16.255.3<br />
forward-addr: 172.16.255.4<br />
forward-addr: 172.16.255.5<br />
forward-addr: 172.16.255.7<br />
forward-zone:<br />
name: "example2.net"<br />
forward-addr: 172.16.255.1<br />
forward-addr: 172.16.255.2<br />
forward-addr: 172.16.255.3<br />
forward-addr: 172.16.255.4<br />
forward-addr: 172.16.255.5<br />
forward-addr: 172.16.255.7<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/named.cache}}<br />
<br />
{{Cmd|/etc/init.d/unbound start}}<br />
{{Cmd|rc-update add unbound}}<br />
{{Cmd|echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf}}<br />
{{Cmd|nsdc rebuild}}<br />
{{Cmd|/etc/init.d/nsd start}}<br />
{{Cmd|rc-update add nsd}}<br />
<br />
== NTP ==<br />
{{Cmd|apk add chrony}}<br />
{{Cmd|/etc/init.d/chronyd start}}<br />
{{Cmd|rc-update add chronyd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start}}<br />
<br />
{{Cmd|rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=65001<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script}}<br />
<br />
{{Cmd|/etc/init.d/opennhrp start}}<br />
<br />
{{Cmd|rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga}}<br />
<br />
{{Cmd|touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start}}<br />
<br />
{{Cmd|rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
<br />
{{Cmd|echo tun >> /etc/modules}}<br />
{{Cmd|modprobe tun}}<br />
{{Cmd|apk add openvpn}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start}}<br />
{{Cmd|rc-update add openvpn}}<br />
<br />
== Extract Certificates ==<br />
<br />
First, extract the certificates used by Openvpn:<br />
<pre><br />
cd /etc/openvpn<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024<br />
openssl pkcs12 -in openvpn-spoke1.pfx -cacerts -nokeys -out /etc/openvpn/cacert.pem<br />
openssl pkcs12 -in openvpn-spoke1.pfx -nocerts -nodes -out /etc/openvpn/serverkey.pem<br />
openssl pkcs12 -in openvpn-spoke1.pfx -nokeys -clcerts -out /etc/openvpn/servercert.pem<br />
chmod 600 /etc/openvpn/*.pem *.pfx<br />
</pre><br />
<br />
Next, extract keys for racoon:<br />
<pre><br />
openssl pkcs12 -in nhrp-spoke1.PFX -cacerts -nokeys -out ca.pem<br />
openssl pkcs12 -in nhrp-spoke1.PFX -nocerts -nodes -out key.pem<br />
openssl pkcs12 -in nhrp-spoke1.PFX -nokeys -clcerts -out cert.pem<br />
</pre><br />
<br />
Finally, restart both affected services:<br />
{{Cmd|/etc/init.d/racoon restart}}<br />
{{Cmd|/etc/init.d/openvpn restart}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall enable vpnc}}<br />
{{Cmd|awall activate}}<br />
{{Cmd|rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu}}<br />
{{Cmd|echo -e "1\tisp1">> /etc/iproute2/rt_tables}}<br />
{{Cmd|echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
With your favorite editor open <code>/etc/network/interfaces</code> and locate the bond0.256 and bond0.257 sections, and add respectively the following lines:<br />
<br />
<pre><br />
...<br />
auto bond0.256<br />
...<br />
...<br />
up ip rule add fwmark 1 table 1 || true<br />
up ip route add default via %ISP1_GW% table 1 || true<br />
<br />
auto bond0.257<br />
...<br />
...<br />
up ip rule add fwmark 2 table 2 || true<br />
up ip route add default via %ISP2_GW% table 2 || true<br />
</pre><br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
# the rule-priority must be a higher number than the priority in /etc/shorewall/route_rules <-- FIXME<br />
rule-priority 20000<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
rule-priority 20000<br />
}<br />
<br />
# ping google dns via ISP1<br />
host 8.8.8.8 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
<br />
# ping opendns via ISP1<br />
host 208.67.222.222 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/pingu start}}<br />
<br />
{{Cmd|rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
<br />
= Troubleshooting the DMVPN =</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9273
Dynamic Multipoint VPN (DMVPN)
2013-08-21T12:34:07Z
<p>Jbilyk: add extract certs</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Spoke Node =<br />
<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
do-not-query-localhost: no<br />
root-hints: "/etc/unbound/named.cache"<br />
forward-zone:<br />
name: "example.net"<br />
forward-addr: 172.16.255.1<br />
forward-addr: 172.16.255.2<br />
forward-addr: 172.16.255.3<br />
forward-addr: 172.16.255.4<br />
forward-addr: 172.16.255.5<br />
forward-addr: 172.16.255.7<br />
forward-zone:<br />
name: "example2.net"<br />
forward-addr: 172.16.255.1<br />
forward-addr: 172.16.255.2<br />
forward-addr: 172.16.255.3<br />
forward-addr: 172.16.255.4<br />
forward-addr: 172.16.255.5<br />
forward-addr: 172.16.255.7<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/named.cache}}<br />
<br />
{{Cmd|/etc/init.d/unbound start}}<br />
{{Cmd|rc-update add unbound}}<br />
{{Cmd|echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf}}<br />
{{Cmd|nsdc rebuild}}<br />
{{Cmd|/etc/init.d/nsd start}}<br />
{{Cmd|rc-update add nsd}}<br />
<br />
== NTP ==<br />
{{Cmd|apk add chrony}}<br />
{{Cmd|/etc/init.d/chronyd start}}<br />
{{Cmd|rc-update add chronyd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start}}<br />
<br />
{{Cmd|rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=65001<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script}}<br />
<br />
{{Cmd|/etc/init.d/opennhrp start}}<br />
<br />
{{Cmd|rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga}}<br />
<br />
{{Cmd|touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start}}<br />
<br />
{{Cmd|rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
<br />
{{Cmd|echo tun >> /etc/modules}}<br />
{{Cmd|modprobe tun}}<br />
{{Cmd|apk add openvpn}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start}}<br />
{{Cmd|rc-update add openvpn}}<br />
<br />
== Extract Certificates ==<br />
<br />
First, extract the certificates used by Openvpn:<br />
<pre><br />
cd /etc/openvpn<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024<br />
openssl pkcs12 -in openvpn-spoke1.pfx -cacerts -nokeys -out /etc/openvpn/cacert.pem<br />
openssl pkcs12 -in openvpn-spoke1.pfx -nocerts -nodes -out /etc/openvpn/serverkey.pem<br />
openssl pkcs12 -in openvpn-spoke1.pfx -nokeys -clcerts -out /etc/openvpn/servercert.pem<br />
chmod 600 /etc/openvpn/*.pem *.pfx<br />
</pre><br />
<br />
Next, extract keys for racoon:<br />
<pre><br />
openssl pkcs12 -in nhrp-spoke1.PFX -cacerts -nokeys -out ca.pem<br />
openssl pkcs12 -in nhrp-spoke1.PFX -nocerts -nodes -out key.pem<br />
openssl pkcs12 -in nhrp-spoke1.PFX -nokeys -clcerts -out cert.pem<br />
</pre><br />
<br />
Finally, restart both affected services:<br />
{{Cmd|/etc/init.d/racoon restart}}<br />
{{Cmd|/etc/init.d/openvpn restart}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall enable vpnc}}<br />
{{Cmd|awall activate}}<br />
{{Cmd|rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu}}<br />
{{Cmd|echo -e "1\tisp1">> /etc/iproute2/rt_tables}}<br />
{{Cmd|echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
With your favorite editor open <code>/etc/network/interfaces</code> and locate the bond0.256 and bond0.257 sections, and add respectively the following lines:<br />
<br />
<pre><br />
...<br />
auto bond0.256<br />
...<br />
...<br />
up ip rule add fwmark 1 table 1 || true<br />
up ip route add default via %ISP1_GW% table 1 || true<br />
<br />
auto bond0.257<br />
...<br />
...<br />
up ip rule add fwmark 2 table 2 || true<br />
up ip route add default via %ISP2_GW% table 2 || true<br />
</pre><br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
# the rule-priority must be a higher number than the priority in /etc/shorewall/route_rules <-- FIXME<br />
rule-priority 20000<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
rule-priority 20000<br />
}<br />
<br />
# ping google dns via ISP1<br />
host 8.8.8.8 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
<br />
# ping opendns via ISP1<br />
host 208.67.222.222 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/pingu start}}<br />
<br />
{{Cmd|rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
<br />
= Troubleshooting the DMVPN =</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9272
Dynamic Multipoint VPN (DMVPN)
2013-08-21T12:30:02Z
<p>Jbilyk: /* OpenVPN */</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Spoke Node =<br />
<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
do-not-query-localhost: no<br />
root-hints: "/etc/unbound/named.cache"<br />
forward-zone:<br />
name: "example.net"<br />
forward-addr: 172.16.255.1<br />
forward-addr: 172.16.255.2<br />
forward-addr: 172.16.255.3<br />
forward-addr: 172.16.255.4<br />
forward-addr: 172.16.255.5<br />
forward-addr: 172.16.255.7<br />
forward-zone:<br />
name: "example2.net"<br />
forward-addr: 172.16.255.1<br />
forward-addr: 172.16.255.2<br />
forward-addr: 172.16.255.3<br />
forward-addr: 172.16.255.4<br />
forward-addr: 172.16.255.5<br />
forward-addr: 172.16.255.7<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/named.cache}}<br />
<br />
{{Cmd|/etc/init.d/unbound start}}<br />
{{Cmd|rc-update add unbound}}<br />
{{Cmd|echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf}}<br />
{{Cmd|nsdc rebuild}}<br />
{{Cmd|/etc/init.d/nsd start}}<br />
{{Cmd|rc-update add nsd}}<br />
<br />
== NTP ==<br />
{{Cmd|apk add chrony}}<br />
{{Cmd|/etc/init.d/chronyd start}}<br />
{{Cmd|rc-update add chronyd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start}}<br />
<br />
{{Cmd|rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=65001<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script}}<br />
<br />
{{Cmd|/etc/init.d/opennhrp start}}<br />
<br />
{{Cmd|rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga}}<br />
<br />
{{Cmd|touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start}}<br />
<br />
{{Cmd|rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
<br />
{{Cmd|echo tun >> /etc/modules}}<br />
{{Cmd|modprobe tun}}<br />
{{Cmd|apk add openvpn}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto udp<br />
port 1194<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start}}<br />
{{Cmd|rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall enable vpnc}}<br />
{{Cmd|awall activate}}<br />
{{Cmd|rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu}}<br />
{{Cmd|echo -e "1\tisp1">> /etc/iproute2/rt_tables}}<br />
{{Cmd|echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
With your favorite editor open <code>/etc/network/interfaces</code> and locate the bond0.256 and bond0.257 sections, and add respectively the following lines:<br />
<br />
<pre><br />
...<br />
auto bond0.256<br />
...<br />
...<br />
up ip rule add fwmark 1 table 1 || true<br />
up ip route add default via %ISP1_GW% table 1 || true<br />
<br />
auto bond0.257<br />
...<br />
...<br />
up ip rule add fwmark 2 table 2 || true<br />
up ip route add default via %ISP2_GW% table 2 || true<br />
</pre><br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
# the rule-priority must be a higher number than the priority in /etc/shorewall/route_rules <-- FIXME<br />
rule-priority 20000<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
rule-priority 20000<br />
}<br />
<br />
# ping google dns via ISP1<br />
host 8.8.8.8 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
<br />
# ping opendns via ISP1<br />
host 208.67.222.222 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/pingu start}}<br />
<br />
{{Cmd|rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
<br />
= Troubleshooting the DMVPN =</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9270
Dynamic Multipoint VPN (DMVPN)
2013-08-21T03:48:51Z
<p>Jbilyk: add inbound openvpn connections to the firewall</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Spoke Node =<br />
<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
do-not-query-localhost: no<br />
root-hints: "/etc/unbound/named.cache"<br />
forward-zone:<br />
name: "example.net"<br />
forward-addr: 172.16.255.1<br />
forward-addr: 172.16.255.2<br />
forward-addr: 172.16.255.3<br />
forward-addr: 172.16.255.4<br />
forward-addr: 172.16.255.5<br />
forward-addr: 172.16.255.7<br />
forward-zone:<br />
name: "example2.net"<br />
forward-addr: 172.16.255.1<br />
forward-addr: 172.16.255.2<br />
forward-addr: 172.16.255.3<br />
forward-addr: 172.16.255.4<br />
forward-addr: 172.16.255.5<br />
forward-addr: 172.16.255.7<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/named.cache}}<br />
<br />
{{Cmd|/etc/init.d/unbound start}}<br />
{{Cmd|rc-update add unbound}}<br />
{{Cmd|echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf}}<br />
{{Cmd|nsdc rebuild}}<br />
{{Cmd|/etc/init.d/nsd start}}<br />
{{Cmd|rc-update add nsd}}<br />
<br />
== NTP ==<br />
{{Cmd|apk add chrony}}<br />
{{Cmd|/etc/init.d/chronyd start}}<br />
{{Cmd|rc-update add chronyd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start}}<br />
<br />
{{Cmd|rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=65001<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script}}<br />
<br />
{{Cmd|/etc/init.d/opennhrp start}}<br />
<br />
{{Cmd|rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga}}<br />
<br />
{{Cmd|touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start}}<br />
<br />
{{Cmd|rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
<br />
{{Cmd|echo tun >> /etc/modules}}<br />
{{Cmd|modprobe tun}}<br />
{{Cmd|apk add openvpn}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto tcp<br />
port 443<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
Set up certs:<br />
<pre><br />
cd /etc/openvpn<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024<br />
openssl pkcs12 -in /etc/openvpn/ssl_server_cert.pfx -cacerts -nokeys -out /etc/openvpn/cacert.pem<br />
openssl pkcs12 -in /etc/openvpn/ssl_server_cert.pfx -nocerts -nodes -out /etc/openvpn/serverkey.pem<br />
openssl pkcs12 -in /etc/openvpn/ssl_server_cert.pfx -nokeys -clcerts -out /etc/openvpn/servercert.pem<br />
chmod 600 /etc/openvpn/*.pem *.pfx<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start}}<br />
{{Cmd|rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": [ "ssh", "https" ],<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall activate}}<br />
<br />
{{Cmd|rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu}}<br />
{{Cmd|echo -e "1\tisp1">> /etc/iproute2/rt_tables}}<br />
{{Cmd|echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
With your favorite editor open <code>/etc/network/interfaces</code> and locate the bond0.256 and bond0.257 sections, and add respectively the following lines:<br />
<br />
<pre><br />
...<br />
auto bond0.256<br />
...<br />
...<br />
up ip rule add fwmark 1 table 1 || true<br />
up ip route add default via %ISP1_GW% table 1 || true<br />
<br />
auto bond0.257<br />
...<br />
...<br />
up ip rule add fwmark 2 table 2 || true<br />
up ip route add default via %ISP2_GW% table 2 || true<br />
</pre><br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
# the rule-priority must be a higher number than the priority in /etc/shorewall/route_rules <-- FIXME<br />
rule-priority 20000<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
rule-priority 20000<br />
}<br />
<br />
# ping google dns via ISP1<br />
host 8.8.8.8 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
<br />
# ping opendns via ISP1<br />
host 208.67.222.222 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/pingu start}}<br />
<br />
{{Cmd|rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
<br />
= Troubleshooting the DMVPN =</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9269
Dynamic Multipoint VPN (DMVPN)
2013-08-21T03:45:13Z
<p>Jbilyk: add openvpn</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|At the time of this writing the recommended Alpine version for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since the kernel has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be okay instead.}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Spoke Node =<br />
<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
do-not-query-localhost: no<br />
root-hints: "/etc/unbound/named.cache"<br />
forward-zone:<br />
name: "example.net"<br />
forward-addr: 172.16.255.1<br />
forward-addr: 172.16.255.2<br />
forward-addr: 172.16.255.3<br />
forward-addr: 172.16.255.4<br />
forward-addr: 172.16.255.5<br />
forward-addr: 172.16.255.7<br />
forward-zone:<br />
name: "example2.net"<br />
forward-addr: 172.16.255.1<br />
forward-addr: 172.16.255.2<br />
forward-addr: 172.16.255.3<br />
forward-addr: 172.16.255.4<br />
forward-addr: 172.16.255.5<br />
forward-addr: 172.16.255.7<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/named.cache}}<br />
<br />
{{Cmd|/etc/init.d/unbound start}}<br />
{{Cmd|rc-update add unbound}}<br />
{{Cmd|echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf}}<br />
{{Cmd|nsdc rebuild}}<br />
{{Cmd|/etc/init.d/nsd start}}<br />
{{Cmd|rc-update add nsd}}<br />
<br />
== NTP ==<br />
{{Cmd|apk add chrony}}<br />
{{Cmd|/etc/init.d/chronyd start}}<br />
{{Cmd|rc-update add chronyd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start}}<br />
<br />
{{Cmd|rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=65001<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script}}<br />
<br />
{{Cmd|/etc/init.d/opennhrp start}}<br />
<br />
{{Cmd|rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga}}<br />
<br />
{{Cmd|touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add the line <code>neighbor %HUB_GRE_IP% remote-as 65000</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start}}<br />
<br />
{{Cmd|rc-update add bgpd}}<br />
<br />
== OpenVPN ==<br />
<br />
{{Cmd|echo tun >> /etc/modules}}<br />
{{Cmd|modprobe tun}}<br />
{{Cmd|apk add openvpn}}<br />
<br />
Set up the config in /etc/openvpn/openvpn.conf<br />
<pre><br />
dev tun<br />
proto tcp<br />
port 443<br />
<br />
server 10.1.128.0 255.255.255.0<br />
push "route 10.0.0.0 255.0.0.0"<br />
push "dhcp-option DNS 10.1.0.1"<br />
<br />
tls-server<br />
ca /etc/openvpn/cacert.pem<br />
cert /etc/openvpn/servercert.pem<br />
key /etc/openvpn/serverkey.pem<br />
<br />
crl-verify /etc/openvpn/crl.pem<br />
<br />
dh /etc/openvpn/dh1024.pem<br />
<br />
persist-key<br />
persist-tun<br />
<br />
keepalive 10 120<br />
<br />
comp-lzo<br />
<br />
status /var/log/openvpn.status<br />
mute 20<br />
verb 3<br />
</pre><br />
<br />
Set up certs:<br />
<pre><br />
cd /etc/openvpn<br />
openssl dhparam -out /etc/openvpn/dh1024.pem 1024<br />
openssl pkcs12 -in /etc/openvpn/ssl_server_cert.pfx -cacerts -nokeys -out /etc/openvpn/cacert.pem<br />
openssl pkcs12 -in /etc/openvpn/ssl_server_cert.pfx -nocerts -nodes -out /etc/openvpn/serverkey.pem<br />
openssl pkcs12 -in /etc/openvpn/ssl_server_cert.pfx -nokeys -clcerts -out /etc/openvpn/servercert.pem<br />
chmod 600 /etc/openvpn/*.pem *.pfx<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/openvpn start}}<br />
{{Cmd|rc-update add openvpn}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": "ssh",<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ]<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "gre1" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall activate}}<br />
<br />
{{Cmd|rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu}}<br />
{{Cmd|echo -e "1\tisp1">> /etc/iproute2/rt_tables}}<br />
{{Cmd|echo -e "2\tisp2">> /etc/iproute2/rt_tables}}<br />
<br />
With your favorite editor open <code>/etc/network/interfaces</code> and locate the bond0.256 and bond0.257 sections, and add respectively the following lines:<br />
<br />
<pre><br />
...<br />
auto bond0.256<br />
...<br />
...<br />
up ip rule add fwmark 1 table 1 || true<br />
up ip route add default via %ISP1_GW% table 1 || true<br />
<br />
auto bond0.257<br />
...<br />
...<br />
up ip rule add fwmark 2 table 2 || true<br />
up ip route add default via %ISP2_GW% table 2 || true<br />
</pre><br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
# the rule-priority must be a higher number than the priority in /etc/shorewall/route_rules <-- FIXME<br />
rule-priority 20000<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
rule-priority 20000<br />
}<br />
<br />
# ping google dns via ISP1<br />
host 8.8.8.8 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
<br />
# ping opendns via ISP1<br />
host 208.67.222.222 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/pingu start}}<br />
<br />
{{Cmd|rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== Commit Configuration ==<br />
{{Cmd|lbu ci}}<br />
<br />
= Hub Node =<br />
<br />
= Troubleshooting the DMVPN =</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9257
Dynamic Multipoint VPN (DMVPN)
2013-08-20T15:51:30Z
<p>Jbilyk: add ntp</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states: [ref?]<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference Linux DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|The recommended version of Alpine for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since it has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be also okay}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Spoke Node =<br />
<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a second is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of your LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
do-not-query-localhost: no<br />
root-hints: "/etc/unbound/named.cache"<br />
forward-zone:<br />
name: "example.net"<br />
forward-addr: 172.16.255.1<br />
forward-addr: 172.16.255.2<br />
forward-addr: 172.16.255.3<br />
forward-addr: 172.16.255.4<br />
forward-addr: 172.16.255.5<br />
forward-addr: 172.16.255.7<br />
forward-zone:<br />
name: "example2.net"<br />
forward-addr: 172.16.255.1<br />
forward-addr: 172.16.255.2<br />
forward-addr: 172.16.255.3<br />
forward-addr: 172.16.255.4<br />
forward-addr: 172.16.255.5<br />
forward-addr: 172.16.255.7<br />
stub-zone:<br />
name: "location1.example.net"<br />
stub-addr: 10.1.0.2<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/named.cache}}<br />
<br />
{{Cmd|/etc/init.d/unbound start}}<br />
{{Cmd|rc-update add unbound}}<br />
{{Cmd|echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: location1.example.net<br />
zonefile: location1.example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/location1.example.net.zone:<br />
<pre><br />
;## location1.example.net authoritative zone<br />
<br />
$ORIGIN location1.example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.location1.example.net. webmaster.location1.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.location1.example.net.<br />
MX 10 mail.location1.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf}}<br />
{{Cmd|nsdc rebuild}}<br />
{{Cmd|/etc/init.d/nsd start}}<br />
{{Cmd|rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start}}<br />
<br />
{{Cmd|rc-update add racoon}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
<br />
interface bond0.8<br />
shortcut-destination<br />
<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=65001<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script}}<br />
<br />
{{Cmd|/etc/init.d/opennhrp start}}<br />
<br />
{{Cmd|rc-update add opennhrp}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga}}<br />
<br />
{{Cmd|touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add lines <code>neighbor %HUB_GRE_IP%...</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start}}<br />
<br />
{{Cmd|rc-update add bgpd}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"ISP1_IF" = "bond0.256",<br />
"ISP2_IF" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": [ "$ISP1_IF", "$ISP2_IF" ] },<br />
"ISP1": { "iface": "$ISP1_IF" },<br />
"ISP2": { "iface": "$ISP2_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": "ssh",<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "out": "ISP1", "mark": 1 },<br />
{ "out": "ISP2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ],<br />
"A_IF": "gre1"<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "$A_IF" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" },<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
{{Cmd|awall activate}}<br />
<br />
{{Cmd|rc-update add iptables}}<br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu}}<br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
# the rule-priority must be a higher number than the priority in /etc/shorewall/route_rules <-- FIXME<br />
rule-priority 20000<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
rule-priority 20000<br />
}<br />
<br />
# ping google dns via ISP1<br />
host 8.8.8.8 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
<br />
# ping opendns via ISP1<br />
host 208.67.222.222 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
</pre><br />
<br />
{{Cmd|/etc/init.d/pingu start}}<br />
<br />
{{Cmd|rc-update add pingu}}<br />
<br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.<br />
<br />
== NTP ==<br />
<br />
{{Cmd|apk add chrony}}<br />
{{Cmd|/etc/init.d/chronyd start}}<br />
{{Cmd|rc-update add chronyd}}<br />
<br />
= Hub Node =<br />
<br />
= Troubleshooting the DMVPN =</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9237
Dynamic Multipoint VPN (DMVPN)
2013-08-19T15:54:59Z
<p>Jbilyk: </p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states:<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|The recommended version of Alpine for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since it has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be also okay}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Spoke Node =<br />
<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a 2nd is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.3 = Management '''(not implemented below yet)'''<br><br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.80 = Voice '''(not implemented below yet)'''<br><br />
bond0.96 = Internet Access Only (no access to the DMVPN network)'''(not implemented below yet)'''<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of you LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type an appropriate another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
do-not-query-localhost: no<br />
root-hints: "/etc/unbound/named.cache"<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 10.1.0.2<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/named.cache}}<br />
<br />
{{Cmd|/etc/init.d/unbound start}}<br />
{{Cmd|rc-update add unbound}}<br />
{{Cmd|echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: example.net<br />
zonefile: example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/example.net.zone:<br />
<pre><br />
;## example.net authoritative zone<br />
<br />
$ORIGIN example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.example.net. webmaster.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.example.net.<br />
MX 10 mail.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf}}<br />
{{Cmd|nsdc rebuild}}<br />
{{Cmd|/etc/init.d/nsd start}}<br />
{{Cmd|rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
interface bond0.8<br />
shortcut-destination<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=65001<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga}}<br />
<br />
{{Cmd|touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add lines <code>neighbor %HUB_GRE_IP%...</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"E_IF" = "bond0.256",<br />
"E_IF2" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": "$E_IF" },<br />
"E2": { "iface": "$E_IF2" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": [ "E", "E2 ],<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": [ "E", "E2" ],<br />
"out": "_fw",<br />
"service": "ssh",<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "E", "E2" ],<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "in": "E", "mark": 1 },<br />
{ "in": "E2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ],<br />
"A_IF": "gre1"<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "$A_IF" }<br />
},<br />
<br />
"filter": [<br />
{ "in": [ "E", "E2" ], "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": [ "E", "E2" ], "service": "ipsec", "action": "accept" },<br />
{<br />
"in": [ "E", "E2" ],<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": [ "E", "E2" ],<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": [ "E", "E2" ], "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": [ "E", "E2" ], "action": "drop" }<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": [ "E", "E2" ] }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu}}<br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
# the rule-priority must be a higher number than the priority in /etc/shorewall/route_rules <-- FIXME<br />
rule-priority 20000<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
rule-priority 20000<br />
}<br />
<br />
# ping google dns via ISP1<br />
host 8.8.8.8 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
<br />
# ping opendns via ISP1<br />
host 208.67.222.222 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
</pre><br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9236
Dynamic Multipoint VPN (DMVPN)
2013-08-19T15:39:19Z
<p>Jbilyk: change vlan IDs</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states:<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|The recommended version of Alpine for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since it has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be also okay}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Spoke Node =<br />
<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a 2nd is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.8 = LAN<br><br />
bond0.64 = DMZ<br><br />
bond0.256 = ISP1<br><br />
bond0.257 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.8'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.8? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of you LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type an appropriate another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.8 configuration for bond0.64, bond0.256 and bond0.257 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
do-not-query-localhost: no<br />
root-hints: "/etc/unbound/named.cache"<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 10.1.0.2<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/named.cache}}<br />
<br />
{{Cmd|/etc/init.d/unbound start}}<br />
{{Cmd|rc-update add unbound}}<br />
{{Cmd|echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.8 stanza in /etc/network/interfaces:<br />
up ip addr add 10.1.0.2/24 dev bond0.8<br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: example.net<br />
zonefile: example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/example.net.zone:<br />
<pre><br />
;## example.net authoritative zone<br />
<br />
$ORIGIN example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.example.net. webmaster.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.example.net.<br />
MX 10 mail.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf}}<br />
{{Cmd|nsdc rebuild}}<br />
{{Cmd|/etc/init.d/nsd start}}<br />
{{Cmd|rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
interface bond0.8<br />
shortcut-destination<br />
interface bond0.64<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=65001<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga}}<br />
<br />
{{Cmd|touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add lines <code>neighbor %HUB_GRE_IP%...</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.8",<br />
"C_IF" = "bond0.64",<br />
"E_IF" = "bond0.256",<br />
"E_IF2" = "bond0.257"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": "$E_IF" },<br />
"E2": { "iface": "$E_IF2" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": [ "E", "E2 ],<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": [ "E", "E2" ],<br />
"out": "_fw",<br />
"service": "ssh",<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "E", "E2" ],<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "in": "E", "mark": 1 },<br />
{ "in": "E2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ],<br />
"A_IF": "gre1"<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "$A_IF" }<br />
},<br />
<br />
"filter": [<br />
{ "in": [ "E", "E2" ], "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": [ "E", "E2" ], "service": "ipsec", "action": "accept" },<br />
{<br />
"in": [ "E", "E2" ],<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": [ "E", "E2" ],<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": [ "E", "E2" ], "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": [ "E", "E2" ], "action": "drop" }<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": [ "E", "E2" ] }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu}}<br />
<br />
Configure pingu to monitor our bond0.256 and bond0.257 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.256 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
# the rule-priority must be a higher number than the priority in /etc/shorewall/route_rules <-- FIXME<br />
rule-priority 20000<br />
}<br />
<br />
interface bond0.257 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
rule-priority 20000<br />
}<br />
<br />
# ping google dns via ISP1<br />
host 8.8.8.8 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
<br />
# ping opendns via ISP1<br />
host 208.67.222.222 {<br />
interval 60<br />
bind-interface bond0.256<br />
}<br />
</pre><br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.256 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.256 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9235
Dynamic Multipoint VPN (DMVPN)
2013-08-19T15:20:16Z
<p>Jbilyk: add spoke node overview</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states:<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|The recommended version of Alpine for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since it has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be also okay}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Spoke Node =<br />
<br />
A local spoke node network has support for multiple ISP connections, along with redundant layer 2 switches. At least one 802.1q capable switch is required, and a 2nd is optional for redundancy purposes. The typical spoke node network looks like:<br />
<br />
[[File:DMVPN-Spoke.png]]<br />
<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.1 = LAN<br><br />
bond0.2 = DMZ<br><br />
bond0.10 = ISP1<br><br />
bond0.11 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.1'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.1? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of you LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type an appropriate another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.1 configuration for bond0.2, bond0.10 and bond0.20 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
do-not-query-localhost: no<br />
root-hints: "/etc/unbound/named.cache"<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 10.1.0.2<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/named.cache}}<br />
<br />
{{Cmd|/etc/init.d/unbound start}}<br />
{{Cmd|rc-update add unbound}}<br />
{{Cmd|echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.1 stanza in /etc/network/interfaces:<br />
up ip addr add 10.1.0.2/24 dev bond0.1<br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: example.net<br />
zonefile: example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/example.net.zone:<br />
<pre><br />
;## example.net authoritative zone<br />
<br />
$ORIGIN example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.example.net. webmaster.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.example.net.<br />
MX 10 mail.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf}}<br />
{{Cmd|nsdc rebuild}}<br />
{{Cmd|/etc/init.d/nsd start}}<br />
{{Cmd|rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
interface bond0.1<br />
shortcut-destination<br />
interface bond0.2<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=65001<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga}}<br />
<br />
{{Cmd|touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add lines <code>neighbor %HUB_GRE_IP%...</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.1",<br />
"C_IF" = "bond0.2",<br />
"E_IF" = "bond0.10",<br />
"E_IF2" = "bond0.11"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": "$E_IF" },<br />
"E2": { "iface": "$E_IF2" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": [ "E", "E2 ],<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": [ "E", "E2" ],<br />
"out": "_fw",<br />
"service": "ssh",<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "E", "E2" ],<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "in": "E", "mark": 1 },<br />
{ "in": "E2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ],<br />
"A_IF": "gre1"<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "$A_IF" }<br />
},<br />
<br />
"filter": [<br />
{ "in": [ "E", "E2" ], "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": [ "E", "E2" ], "service": "ipsec", "action": "accept" },<br />
{<br />
"in": [ "E", "E2" ],<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": [ "E", "E2" ],<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": [ "E", "E2" ], "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": [ "E", "E2" ], "action": "drop" }<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": [ "E", "E2" ] }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu}}<br />
<br />
Configure pingu to monitor our bond0.10 and bond0.11 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.10 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
# the rule-priority must be a higher number than the priority in /etc/shorewall/route_rules <-- FIXME<br />
rule-priority 20000<br />
}<br />
<br />
interface bond0.11 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
rule-priority 20000<br />
}<br />
<br />
# ping google dns via ISP1<br />
host 8.8.8.8 {<br />
interval 60<br />
bind-interface bond0.10<br />
}<br />
<br />
# ping opendns via ISP1<br />
host 208.67.222.222 {<br />
interval 60<br />
bind-interface bond0.10<br />
}<br />
</pre><br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.10 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.10 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9234
Dynamic Multipoint VPN (DMVPN)
2013-08-19T14:59:26Z
<p>Jbilyk: add nsd and unbound</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states:<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|The recommended version of Alpine for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since it has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be also okay}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Spoke Node =<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.1 = LAN<br><br />
bond0.2 = DMZ<br><br />
bond0.10 = ISP1<br><br />
bond0.11 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.1'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.1? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of you LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type an appropriate another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.1 configuration for bond0.2, bond0.10 and bond0.20 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== Recursive DNS ==<br />
{{Cmd|apk add unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, the stub-zone stanza is present:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
do-not-query-localhost: no<br />
root-hints: "/etc/unbound/named.cache"<br />
stub-zone:<br />
name: "example.net"<br />
stub-addr: 10.1.0.2<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/named.cache}}<br />
<br />
{{Cmd|/etc/init.d/unbound start}}<br />
{{Cmd|rc-update add unbound}}<br />
{{Cmd|echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== Local DNS Zone ==<br />
<br />
If you have a DNS zone that is only resolvable internally to your network, you will need a 2nd IP address on your LAN interface, and use NSD to host the zone.<br />
<br />
First, add the following to the end of the bond0.1 stanza in /etc/network/interfaces:<br />
up ip addr add 10.1.0.2/24 dev bond0.1<br />
<br />
Then, install nsd:<br />
{{Cmd|apk add nsd}}<br />
<br />
Create /etc/nsd/nsd.conf:<br />
<pre><br />
server:<br />
ip-address: 10.1.0.2<br />
port: 53<br />
server-count: 1<br />
ip4-only: yes<br />
hide-version: yes<br />
identity: ""<br />
zonesdir: "/etc/nsd"<br />
zone:<br />
name: example.net<br />
zonefile: example.net.zone<br />
</pre><br />
<br />
Create zonefile in /etc/nsd/example.net.zone:<br />
<pre><br />
;## example.net authoritative zone<br />
<br />
$ORIGIN example.net.<br />
$TTL 86400<br />
<br />
@ IN SOA ns1.example.net. webmaster.example.net. (<br />
2013081901 ; serial<br />
28800 ; refresh<br />
7200 ; retry<br />
86400 ; expire<br />
86400 ; min TTL<br />
)<br />
<br />
NS ns1.example.net.<br />
MX 10 mail.example.net.<br />
ns IN A 10.1.0.2<br />
mail IN A 10.1.0.4<br />
</pre><br />
<br />
Check configuration then start:<br />
{{Cmd|nsd-checkconf /etc/nsd/nsd.conf}}<br />
{{Cmd|nsdc rebuild}}<br />
{{Cmd|/etc/init.d/nsd start}}<br />
{{Cmd|rc-update add nsd}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
interface bond0.1<br />
shortcut-destination<br />
interface bond0.2<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
MYAS=65001<br />
<br />
case $1 in<br />
interface-up)<br />
echo "Interface $NHRP_INTERFACE is up"<br />
if [ "$NHRP_INTERFACE" = "gre1" ]; then<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor core" \<br />
-c "neighbor core peer-group"<br />
fi<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
nhs-up)<br />
echo "NHS UP $NHRP_DESTADDR"<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "neighbor $NHRP_DESTADDR remote-as 65000" \<br />
-c "neighbor $NHRP_DESTADDR peer-group core" \<br />
-c "exit" \<br />
-c "exit" \<br />
-c "clear bgp $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
nhs-down)<br />
(<br />
flock -x 200<br />
vtysh -d bgpd \<br />
-c "configure terminal" \<br />
-c "router bgp $MYAS" \<br />
-c "no neighbor $NHRP_DESTADDR"<br />
) 200>/var/lock/opennhrp-script.lock<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga}}<br />
<br />
{{Cmd|touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add lines <code>neighbor %HUB_GRE_IP%...</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.1",<br />
"C_IF" = "bond0.2",<br />
"E_IF" = "bond0.10",<br />
"E_IF2" = "bond0.11"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": "$E_IF" },<br />
"E2": { "iface": "$E_IF2" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": [ "E", "E2 ],<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": [ "E", "E2" ],<br />
"out": "_fw",<br />
"service": "ssh",<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "E", "E2" ],<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "in": "E", "mark": 1 },<br />
{ "in": "E2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ],<br />
"A_IF": "gre1"<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "$A_IF" }<br />
},<br />
<br />
"filter": [<br />
{ "in": [ "E", "E2" ], "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": [ "E", "E2" ], "service": "ipsec", "action": "accept" },<br />
{<br />
"in": [ "E", "E2" ],<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": [ "E", "E2" ],<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": [ "E", "E2" ], "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": [ "E", "E2" ], "action": "drop" }<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": [ "E", "E2" ] }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu}}<br />
<br />
Configure pingu to monitor our bond0.10 and bond0.11 interfaces in <code>/etc/pingu/pingu.conf</code>. Add the hosts to monitor for ISP failover to <code>/etc/pingu/pingu.conf</code> and bind to primary ISP. We also set the ping timeout to 4 seconds.:<br />
<pre><br />
timeout 4<br />
required 2<br />
retry 11<br />
<br />
interface bond0.10 { <br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 1<br />
# the rule-priority must be a higher number than the priority in /etc/shorewall/route_rules <-- FIXME<br />
rule-priority 20000<br />
}<br />
<br />
interface bond0.11 {<br />
# route-table must correspond with mark in /etc/awall/optional/mark.json<br />
route-table 2<br />
rule-priority 20000<br />
}<br />
<br />
# ping google dns via ISP1<br />
host 8.8.8.8 {<br />
interval 60<br />
bind-interface bond0.10<br />
}<br />
<br />
# ping opendns via ISP1<br />
host 208.67.222.222 {<br />
interval 60<br />
bind-interface bond0.10<br />
}<br />
</pre><br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.10 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.10 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9229
Dynamic Multipoint VPN (DMVPN)
2013-08-19T14:37:11Z
<p>Jbilyk: add pingu failover</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states:<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|The recommended version of Alpine for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since it has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be also okay}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Spoke Node =<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.1 = LAN<br><br />
bond0.2 = DMZ<br><br />
bond0.10 = ISP1<br><br />
bond0.11 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.1'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.1? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of you LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type an appropriate another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.1 configuration for bond0.2, bond0.10 and bond0.20 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== DNS ==<br />
{{Cmd|apk add unbound}}<br />
<br />
With your favorite editor open <code>/etc/unbound/unbound.conf</code> and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, uncomment the stub-zone stanza and replace the stub-addr with the appropriate DNS server:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
do-not-query-localhost: no<br />
root-hints: "/etc/unbound/named.cache"<br />
#stub-zone:<br />
# name: "example.net"<br />
# stub-addr: 10.1.0.10<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/named.cache}}<br />
<br />
{{Cmd|/etc/init.d/unbound start}}<br />
{{Cmd|echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
interface bond0.1<br />
shortcut-destination<br />
interface bond0.2<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
vtysh -d bgpd -c "clear bgp $NHRP_DESTADDR" 2>/dev/null || true<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga}}<br />
<br />
{{Cmd|touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add lines <code>neighbor %HUB_GRE_IP%...</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.1",<br />
"C_IF" = "bond0.2",<br />
"E_IF" = "bond0.10",<br />
"E_IF2" = "bond0.11"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": "$E_IF" },<br />
"E2": { "iface": "$E_IF2" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": [ "E", "E2 ],<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": [ "E", "E2" ],<br />
"out": "_fw",<br />
"service": "ssh",<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "E", "E2" ],<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/mark.json'''</code><br />
<pre><br />
{<br />
"description": "Mark traffic based on ISP",<br />
<br />
"import": [ "params", "internet-host" ],<br />
<br />
"route-track": [<br />
{ "in": "E", "mark": 1 },<br />
{ "in": "E2", "mark": 2 }<br />
]<br />
}<br />
</pre><br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ],<br />
"A_IF": "gre1"<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "$A_IF" }<br />
},<br />
<br />
"filter": [<br />
{ "in": [ "E", "E2" ], "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": [ "E", "E2" ], "service": "ipsec", "action": "accept" },<br />
{<br />
"in": [ "E", "E2" ],<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": [ "E", "E2" ],<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": [ "E", "E2" ], "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": [ "E", "E2" ], "action": "drop" }<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": [ "E", "E2" ] }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre><br />
<br />
== ISP Failover ==<br />
<br />
{{Cmd|apk add pingu}}}<br />
<br />
Configure pingu to monitor our bond0.10 and bond0.11 interfaces in ''/etc/pingu/pingu.conf''. Add the hosts to monitor for ISP failover to ''/etc/pingu/pingu.conf'' and bind to primary ISP. We also set the ping timeout to 2.5 seconds.:<br />
<pre><br />
interface bond0.10 { <br />
# route-table must correspond with NUMBER column in /etc/shorewall/providers<br />
route-table 1<br />
# the rule-priority must be a higher number than the priority in /etc/shorewall/route_rules<br />
rule-priority 20000<br />
}<br />
<br />
interface bond0.11 {<br />
# route-table must correspond with NUMBER column in /etc/shorewall/providers<br />
route-table 2<br />
rule-priority 20000<br />
}<br />
<br />
# Ping responses that takes more than 2.5 seconds are considered lost.<br />
timeout 2.5<br />
<br />
# ping google dns via ISP1<br />
host 8.8.8.8 {<br />
interval 60<br />
bind-interface bond0.10<br />
}<br />
<br />
# ping opendns via ISP1<br />
host 208.67.222.222 {<br />
interval 60<br />
bind-interface bond0.10<br />
}<br />
</pre><br />
Now, if both hosts stop responding to pings, ISP-1 will be considered down and all gateways via bond0.10 will be removed from main route table. Note that the gateway will not be removed from the route table '1'. This is so we can continue try ping via bond0.10 so we can detect that the ISP is back online. When ISP starts working again, the gateways will be added back to main route table again.</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)&diff=9226
Dynamic Multipoint VPN (DMVPN)
2013-08-19T14:15:06Z
<p>Jbilyk: add unbound</p>
<hr />
<div>{{Draft}}<br />
<br />
http://alpinelinux.org/about under '''Why the Name Alpine?''' states:<br />
<br />
''The first open-source implementation of Cisco's DMVPN, called OpenNHRP, was written for Alpine Linux.''<br />
<br />
So the aim of this document is to be the reference DMVPN setup, with all the networking services needed for the clients that will use the DMVPN (DNS, DHCP, firewall, etc.).<br />
<br />
= Terminology =<br />
'''NBMA''': ''Non-Broadcast Multi-Access'' network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]<br />
<br />
'''Hub''': the ''Next Hop Server'' (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.<br />
<br />
'''Spoke''': the ''Next Hop Resolution Protocol Client'' (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.<br />
<br />
{{Tip|The recommended version of Alpine for building a DMVPN should be at minimum 2.4.11. Don't use 2.5.x, or 2.6.0 since it has in-tunnel IP fragmentation issues. Alpine 2.6.1 or later should be also okay}}<br />
<br />
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}<br />
<br />
= Spoke Node =<br />
== Alpine Setup ==<br />
We will setup the network interfaces as follows:<br />
<br />
bond0.1 = LAN<br><br />
bond0.2 = DMZ<br><br />
bond0.10 = ISP1<br><br />
bond0.11 = ISP2<br><br />
<br />
Boot Alpine in [[Installation#Basics|diskless mode]] and run <code>setup-alpine</code><br />
<br />
{|class="wikitable"<br />
!'''You will be prompted something like this...'''<br />
!'''Suggestion on what you could enter...'''<br />
|-<br />
|<code>Select keyboard layout [none]:</code><br />
|''Type an appropriate layout for you''<br />
|-<br />
|<code>Select variant:</code><br />
|''Type an appropriate layout for you (if prompted)''<br />
|-<br />
|<code>Enter system hostname (short form, e.g. 'foo') [localhost]:</code><br />
|''Enter the hostname, e.g.'' '''vpnc'''<br />
|-<br />
|<code>Available interfaces are: eth0<br>Enter '?' for help on bridges, bonding and vlans.<br>Which one do you want to initialize? (or '?' done')</code><br />
|''Enter'' '''bond0.1'''<br />
|-<br />
|<code>Available bond slaves are: eth0 eth1<br>Which slave(s) do you want to add to bond0? (or 'done') [eth0]</code><br />
|'''eth0 eth1'''<br />
|-<br />
|<code>IP address for bond0? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>IP address for bond0.1? (or 'dhcp', 'none', '?') [dhcp]:</code><br />
|''Enter the IP address of you LAN interface, e.g.'' '''10.1.0.1'''<br />
|-<br />
|<code>Netmask? [255.255.255.0]:</code><br />
|''Press Enter confirming '255.255.255.0' or type an appropriate another appropriate subnet mask''<br />
|-<br />
|<code>Gateway? (or 'none') [none]:</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Do you want to do any manual network configuration? [no]</code><br />
|'''yes'''<br />
|-<br />
|''Make a copy of the bond0.1 configuration for bond0.2, bond0.10 and bond0.20 (optional) interfaces.<br>Don't forget to add a gateway and a metric value for ISP interfaces when multiple gateways are set.<br>Save and close the file (:wq)''<br />
|-<br />
|<code>DNS domain name? (e.g. 'bar.com') []:</code><br />
|''Enter the domain name of your intranet, e.g.,'' '''example.net'''<br />
|-<br />
|<code>DNS nameservers(s)? []:</code><br />
|'''8.8.8.8 8.8.4.4''' (we will change them later)<br />
|-<br />
|<code>Changing password for root<br>New password:</code><br />
|''Enter a secure password for the console''<br />
|-<br />
|<code>Retype password:</code><br />
|''Retype the above password''<br />
|-<br />
|<code>Which timezone are you in? ('?' for list) [UTC]:</code><br />
|''Press Enter confirming 'UTC'''<br />
|-<br />
|<code>HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]</code><br />
|''Press Enter confirming 'none'''<br />
|-<br />
|<code>Enter mirror number (1-9) or URL to add (or r/f/e/done) [f]:</code><br />
|''Select a mirror close to you and press Enter''<br />
|-<br />
|<code>Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]:</code><br />
|''Press Enter confirming 'openssh'''<br />
|-<br />
|<code>Which NTP client to run? ('openntpd', 'chrony' or 'none') [chrony]:</code><br />
|''Press Enter confirming 'chrony'''<br />
|-<br />
|<code>Which disk(s) would you like to use? (or '?' for help or 'none') [none]:</code><br />
|''Press Enter confirming 'none' or type 'none' if needed''<br />
|-<br />
|<code>Enter where to store configs ('floppy', 'usb' or 'none') [usb]:</code><br />
|''Press Enter confirming 'usb'''<br />
|-<br />
|<code>Enter apk cache directory (or '?' or 'none') [/media/usb/cache]:</code><br />
|''Press Enter confirming '/media/usb/cache'''<br />
|}<br />
<br />
== Bonding ==<br />
Update the bonding configuration:<br />
<br />
echo bonding mode=balance-tlb miimon=100 updelay=500 >> /etc/modules<br />
<br />
== DNS ==<br />
{{Cmd|apk add unbound}}<br />
<br />
Edit /etc/unbound/unbound.conf and add the following configuration. If you have a domain that you want unbound to resolve but is internal to your network only, uncomment the stub-zone stanza and replace the stub-addr with the appropriate DNS server:<br />
<pre><br />
server:<br />
verbosity: 1<br />
interface: 10.1.0.1<br />
do-ip4: yes<br />
do-ip6: no<br />
do-udp: yes<br />
do-tcp: yes<br />
do-daemonize: yes<br />
access-control: 10.1.0.0/16 allow<br />
access-control: 127.0.0.0/8 allow<br />
do-not-query-localhost: no<br />
root-hints: "/etc/unbound/named.cache"<br />
#stub-zone:<br />
# name: "example.net"<br />
# stub-addr: 10.1.0.10<br />
python:<br />
remote-control:<br />
control-enable: no<br />
</pre><br />
<br />
Fetch the latest copy of root hints:<br />
<br />
{{Cmd|wget http://ftp.internic.net/domain/named.cache -O /etc/unbound/named.cache}}<br />
<br />
{{Cmd|/etc/init.d/unbound start}}<br />
{{Cmd|echo nameserver 10.1.0.1 > /etc/resolv.conf}}<br />
<br />
== GRE Tunnel ==<br />
With your favorite editor open <code>/etc/network/interfaces</code> and add the following:<br />
<br />
auto gre1<br />
iface gre1 inet static<br />
pre-up ip tunnel add $IFACE mode gre ttl 64 tos inherit key 12.34.56.78 || true<br />
address 172.16.1.1<br />
netmask 255.255.0.0<br />
post-down ip tunnel del $IFACE || true<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|ifup gre1}}<br />
<br />
== IPSEC ==<br />
{{Cmd|apk add ipsec-tools}}<br />
<br />
With your favorite editor open <code>/etc/ipsec.conf</code> and change the content to the following:<br />
<br />
spdflush;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P out ipsec esp/transport//require;<br />
spdadd 0.0.0.0/0 0.0.0.0/0 gre -P in ipsec esp/transport//require;<br />
<br />
With your favorite editor open <code>/etc/racoon/racoon.conf</code> and change the content to the following:<br />
<br />
<pre><br />
remote anonymous {<br />
exchange_mode main;<br />
lifetime time 2 hour;<br />
certificate_type x509 "/etc/racoon/cert.pem" "/etc/racoon/key.pem";<br />
ca_type x509 "/etc/racoon/ca.pem";<br />
my_identifier asn1dn;<br />
nat_traversal on;<br />
script "/etc/opennhrp/racoon-ph1dead.sh" phase1_dead;<br />
dpd_delay 120;<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group modp4096;<br />
}<br />
proposal {<br />
encryption_algorithm aes 256;<br />
hash_algorithm sha1;<br />
authentication_method rsasig;<br />
dh_group 2;<br />
}<br />
}<br />
<br />
sainfo anonymous {<br />
pfs_group 2;<br />
lifetime time 2 hour;<br />
encryption_algorithm aes 256;<br />
authentication_algorithm hmac_sha1;<br />
compression_algorithm deflate;<br />
}<br />
</pre><br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/racoon start}}<br />
<br />
== Next Hop Resolution Protocol (NHRP) ==<br />
{{Cmd|apk add opennhrp}}<br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp.conf</code> and change the content to the following:<br />
<br />
<pre><br />
interface gre1<br />
dynamic-map 172.16.0.0/16 hub.example.com<br />
shortcut<br />
redirect<br />
non-caching<br />
interface bond0.1<br />
shortcut-destination<br />
interface bond0.2<br />
shortcut-destination<br />
</pre><br />
<br />
With your favorite editor open <code>/etc/opennhrp/opennhrp-script</code> and change the content to the following:<br />
<br />
<pre><br />
#!/bin/sh<br />
<br />
case $1 in<br />
interface-up)<br />
ip route flush proto 42 dev $NHRP_INTERFACE<br />
ip neigh flush dev $NHRP_INTERFACE<br />
;;<br />
peer-register)<br />
;;<br />
peer-up)<br />
if [ -n "$NHRP_DESTMTU" ]; then<br />
ARGS=`ip route get $NHRP_DESTNBMA from $NHRP_SRCNBMA | head -1`<br />
ip route add $ARGS proto 42 mtu $NHRP_DESTMTU<br />
fi<br />
echo "Create link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
racoonctl establish-sa -w isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA || exit 1<br />
racoonctl establish-sa -w esp inet $NHRP_SRCNBMA $NHRP_DESTNBMA gre || exit 1 <br />
vtysh -d bgpd -c "clear bgp $NHRP_DESTADDR" 2>/dev/null || true<br />
;;<br />
peer-down)<br />
echo "Delete link from $NHRP_SRCADDR ($NHRP_SRCNBMA) to $NHRP_DESTADDR ($NHRP_DESTNBMA)"<br />
if [ "$NHRP_PEER_DOWN_REASON" != "lower-down" ]; then<br />
racoonctl delete-sa isakmp inet $NHRP_SRCNBMA $NHRP_DESTNBMA<br />
fi<br />
ip route del $NHRP_DESTNBMA src $NHRP_SRCNBMA proto 42<br />
;;<br />
route-up)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is up"<br />
ip route replace $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42 via $NHRP_NEXTHOP dev $NHRP_INTERFACE<br />
ip route flush cache<br />
;;<br />
route-down)<br />
echo "Route $NHRP_DESTADDR/$NHRP_DESTPREFIX is down"<br />
ip route del $NHRP_DESTADDR/$NHRP_DESTPREFIX proto 42<br />
ip route flush cache<br />
;;<br />
esac<br />
<br />
exit 0<br />
<br />
</pre><br />
<br />
Save and close the file. Make it executable:<br />
<br />
{{Cmd|chmod +x /etc/opennhrp/opennhrp-script}}<br />
<br />
== BGP ==<br />
{{Cmd|apk add quagga}}<br />
<br />
{{Cmd|touch /etc/quagga/zebra.conf}}<br />
<br />
With your favorite editor open <code>/etc/quagga/bgpd.conf</code> and change the content to the following:<br />
<br />
<pre><br />
password strongpassword<br />
enable password strongpassword<br />
log syslog<br />
<br />
access-list 1 remark Command line access authorized IP<br />
access-list 1 permit 127.0.0.1<br />
line vty<br />
access-class 1<br />
<br />
hostname vpnc.example.net<br />
<br />
router bgp 65001<br />
bgp router-id 172.16.1.1<br />
network 10.1.0.0/16<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
neighbor %HUB_GRE_IP% remote-as 65000<br />
...<br />
</pre><br />
<br />
Add lines <code>neighbor %HUB_GRE_IP%...</code> for each '''Hub''' host you have in your NBMA cloud.<br />
<br />
Save and close the file.<br />
<br />
{{Cmd|/etc/init.d/bgpd start}}<br />
<br />
== Firewall ==<br />
{{Cmd|apk add awall}}<br />
<br />
With your favorite editor, edit the following files and set their contents as follows:<br />
<br />
<br />
<code>'''/etc/awall/optional/params.json'''</code><br />
<pre><br />
{<br />
"description": "params",<br />
<br />
"variable": {<br />
"B_IF" = "bond0.1",<br />
"C_IF" = "bond0.2",<br />
"E_IF" = "bond0.10",<br />
"E_IF2" = "bond0.11"<br />
}<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/internet-host.json'''</code><br />
<pre><br />
{<br />
"description": "Internet host",<br />
<br />
"import": "params",<br />
<br />
"zone": {<br />
"E": { "iface": "$E_IF" }<br />
},<br />
<br />
"filter": [<br />
{<br />
"in": "E",<br />
"service": "ping",<br />
"action": "accept",<br />
"flow-limit": { "count": 10, "interval": 6 }<br />
},<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"service": "ssh",<br />
"action": "accept",<br />
"conn-limit": { "count": 3, "interval": 60 }<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"service": [ "dns", "http", "ntp" ],<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"service": [ "ping", "ssh" ],<br />
"action": "accept"<br />
}<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/dmvpn.json'''</code><br />
<pre><br />
{<br />
"description": "DMVPN router",<br />
<br />
"import": "internet-host",<br />
<br />
"variable": {<br />
"A_ADDR": [ "10.0.0.0/8", "172.16.0.0/16" ],<br />
"A_IF": "gre1"<br />
},<br />
<br />
"zone": {<br />
"A": { "addr": "$A_ADDR", "iface": "$A_IF" }<br />
},<br />
<br />
"filter": [<br />
{ "in": "E", "out": "_fw", "service": "ipsec", "action": "accept" },<br />
{ "in": "_fw", "out": "E", "service": "ipsec", "action": "accept" },<br />
{<br />
"in": "E",<br />
"out": "_fw",<br />
"ipsec": "in",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
{<br />
"in": "_fw",<br />
"out": "E",<br />
"ipsec": "out",<br />
"service": "gre",<br />
"action": "accept"<br />
},<br />
<br />
{ "in": "_fw", "out": "A", "service": "bgp", "action": "accept" },<br />
{ "in": "A", "out": "_fw", "service": "bgp", "action": "accept"},<br />
{ "out": "E", "dest": "$A_ADDR", "action": "reject" }<br />
]<br />
}<br />
</pre><br />
<br />
<br />
<code>'''/etc/awall/optional/vpnc.json'''</code><br />
<pre><br />
{<br />
"description": "VPNc",<br />
<br />
"import": [ "params", "internet-host", "dmvpn" ],<br />
<br />
"zone": {<br />
"B": { "iface": "$B_IF" },<br />
"C": { "iface": "$C_IF" }<br />
},<br />
<br />
<br />
"policy": [<br />
{ "in": "A", "action": "accept" },<br />
{ "in": "B", "out": "A", "action": "accept" },<br />
{ "in": "C", "out": [ "A", "E" ], "action": "accept" },<br />
{ "in": "E", "action": "drop" }<br />
{ "in": "_fw", "out": "A", "action": "accept" }<br />
],<br />
<br />
"snat": [<br />
{ "out": "E" }<br />
],<br />
<br />
"filter": [<br />
{<br />
"in": "A",<br />
"out": "_fw",<br />
"service": [ "ping", "ssh", "http", "https" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": [ "B", "C" ],<br />
"out": "_fw",<br />
"service": [ "dns", "ntp", "http", "https", "ssh" ],<br />
"action": "accept"<br />
},<br />
<br />
{<br />
"in": "_fw",<br />
"out": [ "B", "C" ],<br />
"service": [ "dns", "ntp" ],<br />
"action": "accept"<br />
},<br />
<br />
{ <br />
"in": [ "A", "B", "C" ],<br />
"out": "_fw",<br />
"proto": "icmp",<br />
"action": "accept"<br />
}<br />
<br />
]<br />
}<br />
</pre></div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Installation&diff=9161
Installation
2013-07-26T18:46:03Z
<p>Jbilyk: add link to Rackspace install doc</p>
<hr />
<div>The following information will assist you with the installation of [http://alpinelinux.org/about Alpine Linux].<br />
[[Image:hdd_mount.png|left|link=]]<br />
<br /><br />
<br />
== Installation Quick-Start in 3 Easy Steps ==<br />
<div style="float:left; font-size:30px; font-weight:bold;"><br />
1st<br />
</div><br />
<div style="margin-left:65px; background-color:#EDF2F2; border-style:solid; border-color:#6F7C91; border-width:0px; border-left-width:5px; min-height:55px; padding:5px;"><br />
[http://alpinelinux.org/downloads Download] the latest stable-release ISO.<br />
</div><br />
<br />
<br />
<div style="float:left; font-size:30px; font-weight:bold;"><br />
2nd<br />
</div><br />
<div style="margin-left:65px; background-color:#E0E9E9; border-style:solid; border-color:#606A82; border-width:0px; border-left-width:5px; min-height:55px; padding:5px;"><br />
[[Burning ISOs|Burn the ISO onto a blank CD]] using your favorite CD burning software.<br />
</div><br />
<br />
<br />
<div style="float:left; font-size:30px; font-weight:bold;"><br />
3rd<br />
</div><br />
<div style="margin-left:65px; background-color:#9faecc; border-style:solid; border-color:#324065; border-width:0px; border-left-width:5px; min-height:55px; padding:5px;"><br />
Boot from the CD, login as root with no password, and voilà! Enjoy Alpine Linux!<br />
</div><br />
<br />
{{Clear}}<br />
One of the [[Installation#Post-Install|first commands you might want to use]] is <code>[[setup-alpine]]</code>.<br />
<br />
== Installation Handbook ==<br />
=== Basics ===<br />
Alpine can be used in any of three modes:<br />
<dl><br />
<dt>diskless mode<br />
<dd>You'll boot from read-only medium such as the installation CD, a [[Create a Bootable USB|USB key]], or a [[Create a Bootable Compact Flash|Compact Flash card]]. {{Tip| To prepare either a USB or Compact Flash card, you can use the <code>[[setup-bootable]]</code> script; see the pages linked above for details.}} When you use Alpine in this mode, you need to use [[Alpine local backup|Alpine Local Backup (lbu)]] to save your modifications between reboots. That requires some writable medium, usually removable. {{Note| When the <code>[[setup-alpine]]</code> script asks for a disk, say "none". It will then prompt whether you'd like to preserve modifications on any writable medium.}}<br />
<dt>data mode<br />
<dd>As in diskless mode, your OS is run from a read-only medium. However, here a writable partition (usually on a hard disk) is used to store the data in {{Path|/var}}. That partition is accessed directly, rather than copied into a tmpfs; so this is better-suited to uses where large amounts of data need to be preserved between reboots. {{Note| The <code>[[setup-alpine]]</code> script handles installing Alpine in this mode, too, when you supply a writable partition instead of "none", and request mode "data".}} This mode may be used for mailspools, database and log servers, and so on.<br />
<dt>sys mode<br />
<dd>This is a [[Install to disk|traditional hard-disk install]] (see link for details). <!-- includes [[Installing Alpine on HDD overwriting everything]] --> Both the boot system and your modifications are written to the hard disk, in a standard Linux hierarchy. {{Note| The <code>[[setup-alpine]]</code> script handles installing Alpine in this mode, too, when you supply a writable partition instead of "none", and request mode "sys". By default, it will create three partions on your disk, for {{Path|/boot}}, {{Path|/}}, and {{Path|swap}}; however you can also [[Setting up disks manually|partition your disk manually]].<br />
}} This mode may be used for desktops, development boxes, and virtual servers.<br />
<!-- [[Native Harddisk Install 1.6]] Obsolete --><br />
</dl><br />
<br />
=== Advanced ===<br />
* [[Tutorials_and_Howtos#Storage|Setting up storage with RAID, LVM, LUKS encryption, iSCSI, or suchlike]]<br />
* [[Setting up disks manually]]<br />
* [[Bootmanagers]]<br />
* [[Migrating data]]<br />
* Details about [[Alpine setup scripts]]<br />
<br />
* [[Installing Alpine on HDD dualbooting|Install to HDD with dual-boot]]<br />
* [[Replacing non-Alpine Linux with Alpine remotely]]<br />
<!-- [[Installing Xubuntu using Alpine boot floppy]] Obsolete --><br />
<!-- [[Installing Alpine Linux on USB Automated]] Obsolete --><br />
<br />
<!-- If you edit the following, please coordinate with Developer_Documentation#Configuring_your_system. Note that these two sections are not exact duplicates. --><br />
* [[Installing Alpine Linux in a chroot]]<br />
<br />
* Install Alpine on [[Install Alpine on VirtualBox|VirtualBox]], [[Install Alpine on VMware|VMware]], [[Install Alpine on coLinux|coLinux]], [[Qemu]], <!-- includes [[Install Alpine in Qemu]], [[Running Alpine in Qemu Live mode]], [[Running Alpine Linux As a QEMU networked Guest]] -->, [[Install Alpine on Amazon EC2|Amazon EC2]], or [[Install Alpine on Rackspace|RackSpace]]<br />
<br />
* [[Xen Dom0]] ''(Setting up Alpine as a dom0 for Xen hypervisor)''<br />
** [[Xen Dom0 on USB or SD]]<br />
** [[Create Alpine Linux PV DomU]]<br />
** [[Xen LiveCD]]<br />
<br />
* [[Setting up a basic vserver]]<br />
* [[Setting up the build environment on HDD]]<br />
* [[Setting up a compile vserver]] for official or for [[Setting up a compile vserver for third party packages|third party]] packages<br />
<!-- [[Create an Alpine 1.9 vserver template]] --><br />
<br />
=== Post-Install ===<br />
<!-- If you edit this, please coordinate with and Tutorials_and_Howtos#Post-Install and Developer_Documentation#Package_management. Note that these three sections are not exact duplicates. --><br />
<br />
<!-- [[Configure Networking]] --><br />
* [[Tutorials_and_Howtos#Networking|Setting up Networking]]<br />
* [[Alpine Linux package management|Package Management (apk)]] ''(How to add/remove packages on your Alpine)''<br />
<!-- [[Alpine Linux package management#Local_Cache|How to enable APK caching]] --><br />
* [[Alpine local backup|Alpine local backup (lbu)]] ''(Permanently store your modifications in case your box needs reboot)''<br />
** [[Back Up a Flash Memory Installation]]<br />
** [[Manually editing a existing apkovl]]<br />
* [[Alpine Linux Init System|Init System (OpenRC)]] ''(Configure a service to automatically boot at next reboot)''<br />
** [[Multiple Instances of Services]]<br />
<!-- [[Writing Init Scripts]] --><br />
<br />
* [[Upgrading Alpine]]<br />
<!-- Obsolete<br />
[[Upgrading Alpine - v1.9.x]]<br />
[[Upgrading Alpine - CD v1.8.x]]<br />
[[Upgrading Alpine - HD v1.8.x]]<br />
[[Upgrade to repository main|Upgrading to signed repositories]]<br />
--><br />
<br />
* [[Setting up a ssh-server]] ''(Using ssh is a good way to administer your box remotely)''<br />
* [[setup-acf]] ''(Configures ACF (webconfiguration) so you can manage your box through https)''<br />
* [[Changing passwords for ACF|Changing passwords]]<br />
<br />
<!-- [[Running glibc programs]] Installation and Dev --><br />
<br />
<br />
=== Install based on eglibc ===<br />
* [[Setting the timezone]]<br />
<br />
=== Further Help and Information ===<br />
* [[FAQ|FAQs]]<br />
* [[Tutorials and Howtos]]<br />
* [[Contribute|How to Contribute]]<br />
* [[Developer Documentation]]<br />
<br />
[[Category:Installation]]</div>
Jbilyk
https://wiki.alpinelinux.org/w/index.php?title=Install_Alpine_on_Rackspace&diff=9160
Install Alpine on Rackspace
2013-07-26T18:44:23Z
<p>Jbilyk: polish up</p>
<hr />
<div><br />
== Create a minimal rackspace server ==<br />
Debian 7<br />
<br />
512MB, 20GB<br />
<br />
<br />
== Copy settings from existing server into apkovl ==<br />
<br />
The first step is to create Alpine configuration file with basic configuration of the host. We need the new box to start networking and ssh in the beginning so we can reconnect to it after reboot.<br />
<br />
Create basic layout for the overlay:<br />
mkdir overlay<br />
cd overlay<br />
mkdir -p etc/ssh etc/network etc/runlevels/{default,boot,sysinit,shutdown} root/.ssh etc/lbu<br />
<br />
If you want to keep the existing host identity (e.g. SSH key), you can copy them over:<br />
<br />
cp -a /etc/{passwd,group,shadow,gshadow,hostname,resolv.conf,network/interfaces,ssh} etc/<br />
cp /etc/network/interfaces etc/network<br />
<br />
Copy over your ssh authorized_keys and make sure its included in future:<br />
cp -a /root/.ssh/authorized_keys root/.ssh<br />
echo "/root/.ssh" > etc/lbu/include<br />
<br />
<br />
Edit etc/passwd and change bash to /bin/sh.<br />
sed -i -e '/^root:/s:/bin/bash:/bin/sh:' etc/passwd<br />
<br />
{{Note|If you don't do this, nobody (even with physical access) will be able to log into the machine.}}<br />
<br />
'''Make sure there is no whitespace at end of lines''' in interfaces file. Busybox ifup is very picky.<br />
<br />
Create the apk world (/etc/apk/world) with essential packages:<br />
echo "alpine-base iproute2 openssh bash" > etc/apk/world<br />
<br />
(bash is technically not needed, but include it in case you forgot to edit your etc/passwd file correctly)<br />
<br />
'''Double check the IP configuration and ssh keys.'''<br />
<br />
Finally, make the essential services start up automatically and create the overlay file:<br />
ln -s /etc/init.d/{hwclock,modules,sysctl,hostname,bootmisc,syslog} etc/runlevels/boot/<br />
ln -s /etc/init.d/{devfs,dmesg,mdev,hwdrivers} etc/runlevels/sysinit/<br />
ln -s /etc/init.d/{networking,sshd} etc/runlevels/default/<br />
ln -s /etc/init.d/{mount-ro,killprocs,savecache} etc/runlevels/shutdown/<br />
tar czf ../host.apkovl.tar.gz *<br />
<br />
Verify the overlay with "tar tzf" to see that it contains everything in proper places, and ensure it is in the / directory<br />
<br />
tar ../tzvf host.apkovl.tar.gz<br />
cp ../host.apkovl.tar.gz /<br />
<br />
== Install Alpine cd-rom image to hard disk ==<br />
<br />
We need to copy over two sets of information: the boot kernel (kernel, initramdisk and boot configuration) and operating system boot data (overlay, apk packages and kernel modules).<br />
<br />
Download an alpine iso and mount it; for example<br />
<br />
wget http://dl-4.alpinelinux.org/alpine/v2.6/releases/x86_64/alpine-2.6.2-x86_64.iso<br />
mkdir /cdrom<br />
mount alpine*.iso /cdrom -o loop<br />
<br />
Copy the contents of cd-rom image to root of current installation, then setup grub:<br />
<pre><br />
cp -a /cdrom/* /<br />
<br />
cat - >target/boot/grub/grub.conf <<EOF <br />
default=0<br />
timeout=3<br />
hiddenmenu<br />
<br />
title Alpine Linux<br />
root (hd0)<br />
kernel /boot/grsec alpine_dev=xvda1:ext3 modules=loop,squashfs,sd-mod,ext3 console=hvc0 pax_nouderef BOOT_IMAGE=/boot/grsec<br />
initrd /boot/grsec.gz<br />
EOF<br />
<br />
ln -sf ./grub.conf target/boot/grub/menu.lst<br />
</pre><br />
<br />
Reboot and check that all came back as expected.</div>
Jbilyk