Juhtmeta võrgu kontroller23. Apr '15

Sissejuhatus

Käesolevas näites ehitame keskse DHCP serveriga juhtmeta võrgu kasutades Debian masinat ning TP-Link WDR4300 marsruutereid:

802.1Q VLAN sildistamine WPA2 turvatud 802.11abgn Avalik võrk 802.11abgn Internet DHCP server DNS puhver

Keskse kontrolleriga topoloogia

Pädeva juhtmeta võrgu ehitamiseks on vaja:

  • 5GHz tuge, et pakkuda paremat läbilaskevõimet uutele nutiseadmetele

  • 2.4GHz tuge et olla tagurpidi ühilduv vanemate seadmetega

  • Paigaldada ligipääsupunkt igasse ruumi kuna 5GHz levib märgatavalt vähem kui 2.4GHz

  • Piirata ribalaiust 20MHz peale 2.4GHz sagedusel

  • Pakkuda 802.11n tuge kindlasti 5GHz sagedusvahemikel

  • Pakkuda kiirusepiirangutega krüpteerimata võrku külalistele ning ...

  • Pakkuda privilegeeritud krüpteeritud WPA2 või isikulise autentimisega (RADIUS) võrku

  • Viimase kahe punkti täitmiseks on vaja kas mitut raadiot seadmes või multi-SSID tuge

  • POE tuge või vähemalt pädevat pingestabilisaatorit seadmes

Käesolevas kirjatükis püüan välja tuua variandi mis peaks rahuldama äriklassi vajadusi kui ka olema taskukohane, nimelt WDR4300 ruutereid müüakse 54 EUR tükk. Keskse lüüsina kasutatavaks masinaks sobib suvaline vähegi korralikum PC raud kuhu sisse peab pistma lihtsalt kaks gigabitist võrguliidest. Vaja on vaid ettevõtlikkust ja taipu.

TP-Link WDR4300 näol on tegu kallimaotsa koduse ruuteriga, mille südameks on Atherose toodetud MIPS protsessor, mille külge on ühendatud Qualcomm Atheros AR934x raadio kasutamiseks sagedusel 2.4GHz ning teine Qualcomm Atheros AR9580 raadio, mis istub PCI Express siinil, see on mõeldud 5GHz jaoks. TP-Link WDR4300 toiteplokk on disainitud 12V jaoks, kuid testimise käigus on selgunud et ruuter töötab stabiilselt ka 5V peal.

img/tp-link-wdr4300-poe-injector.jpg

TP-Link WDR4300 PoE-injectoriga

Tehasest tulnud WDR4300 on läbi mõeldud alglaaduriga. Hoides all reset nuppu ning ruuterit sisselülitades võtab ruuter ajutiselt omale IP aadressiks 192.168.0.86 ning küsib üle TFTP faili nimega wdr4300v1_tp_recovery.bin IP-lt 192.168.0.66. See funktsionaalsus on ilmselt turvakaalutlustel kasutatav ainult LAN pesadel (1 kuni 4).

Debiani seadistused

Paigalda keskse lüüsina kasutatavasse masinasse Debian ning pane see võrke marsruutima, DHCP serverit ja DNS puhvrit mängima.

Lisaks paigalda VLAN-idega majandamise vahendid:

sudo apt-get install vlan

Lähtesta /etc/network/interfaces:

# Loopback device
auto lo
interface lo inet loopback

# Upstream connection
auto eth0
iface eth0 inet dhcp

# Wired network
auto eth1 inet static
iface eth1 inet static
    address 10.55.0.254
    netmask 255.255.255.0

Parooliga kaitstud juhtmeta võrgu liides failis /etc/network/interfaces.d/private:

# VLAN for WPA protected AP-s
auto eth1.3
iface eth1.3 inet static
    address 10.55.3.254
    netmask 255.255.255.0

Külaliste võrguliides failis /etc/network/interfaces.d/public:

# VLAN for guest AP-s
auto eth1.4
iface eth1.4 inet static
    address 10.55.4.254
    netmask 255.255.255.0

TP-Link WDR4300 püsivara üle laskmiseks lisa ka /etc/network/interfaces.d/flashing:

# Network for Flashing devices
auto eth1.2
iface eth1.2
    address 192.168.0.66
    netmask 255.255.255.0

Marsruuteri tõmmise ettevalmistamine

Laadi alla OpenWrt image builder ning paki see lahti:

wget https://downloads.openwrt.org/barrier_breaker/14.07/ar71xx/generic/OpenWrt-ImageBuilder-ar71xx_generic-for-linux-x86_64.tar.bz2
tar xvjf OpenWrt-ImageBuilder-ar71xx_generic-for-linux-x86_64.tar.bz2

Tee kataloog OpenWrt tõmmise failide jaoks:

mkdir -p overlay/etc/

Sinna sisse loo fail overlay/etc/rc.local:

# Grab MAC address of second PHY, that's also the MAC written on the router
MAC="$(cat /sys/devices/pci0000:00/0000:00:00.0/ieee80211/phy1/macaddress)"
SOURCE="rsync://192.168.0.66:/$MAC/"
TARGET="/etc/"

# Reboot if there were changes
if [ -n "$(rsync -ricppgo $SOURCE $TARGET)" ]; then
    echo "There were configuration changes, rebooting"
    reboot
fi
exit 0

Ning muuda see käivitatavaks:

chmod +x overlay/etc/rc.local

Viimase sammuna lase tõmmise generaatoril fail valmis küpsetada:

make image \
    PROFILE=TLWDR4300 \
    FILES="overlay/" \
    PACKAGES="luci luci-app-qos luci-app-firewall luci-app-commands \
        rsync htop iftop tcpdump nmap nano -dnsmasq -odhcpd -telnetd"

Tõmmise serveerimine

Paigalda TFTP server:

apt-get install atftpd
apt-get remove openbsd-inetd

Liiguta tõmmis TFTP serveri juurikasse:

sudo cp \
    bin/ar71xx/openwrt-ar71xx-generic-tl-wdr4300-v1-squashfs-factory.bin \
    /srv/tftp/wdr4300v1_tp_recovery.bin

Seadista TFTP serverit failis /etc/default/atftp:

USE_INETD=false
OPTIONS="--port 69 --bind-address 192.168.0.66 --tftpd-timeout 300 --retry-timeout 5 --maxthread 100 --verbose=5 /srv/tftp"

Taaskäivita TFTP server:

service atftpd restart

Marsruuterite seadistamine

Debiani masinas paigalda rsync ruuteritele seadistuste jagamiseks:

apt-get install rsync

Luba rsync deemonina failis /etc/default/rsync:

RSYNC_ENABLE=true

Loo võrgu seadistuste jaoks fail /etc/wireless.yml:

timezone: 'EET-2EEST,M3.5.0/3,M10.5.0/4'
password: 'hotspotiadminniparool'

networks:
    public:
        ssid: 'UbinitsaAvalik'
    protected:
        ssid: 'Ubinitsa'
        key: 'salakala'

nodes:
    aula:
        model: wdr4300
        mac: "14:cc:20:12:34:56"
        cha: 149
        chb: 3
    ruum102:
        model: wdr4300
        mac: "14:cc:20:12:34:57"
        cha: 157
        chb: 1
    ruum103:
        model: wdr4300
        mac: "14:cc:20:12:34:58"
        cha: 36
        chb: 6
    ruum201:
        model: wdr4300
        mac: "14:cc:20:12:34:59"
        cha: 44
        chb: 11
    ruum202:
        model: wdr4300
        mac: "14:cc:20:12:34:60"
        cha: 157
        chb: 1
    ruum204:
        model: wdr3400
        mac: "14:cc:20:12:34:61"
        cha: 149
        chb: 3
    psyhholoog:
        model: wdr3400
        mac: "14:cc:20:12:34:62"
        cha: 36
        chb: 6
    ruum301:
        model: wdr3400
        mac: "14:cc:20:12:34:63"
        cha: 157
        chb: 1
    ruum304:
        model: wdr3400
        mac: "14:cc:20:12:34:64"
        cha: 149
        chb: 3
    ruum309:
        model: wdr3400
        mac: "14:cc:20:12:34:65"
        cha: 36
        chb: 6
    ruum321:
        model: wdr3400
        mac: "14:cc:20:12:34:66"
        cha: 44
        chb: 9
    raamatukogu:
        model: wdr3400
        mac: "14:cc:20:12:34:67"
        cha: 44
        chb: 9

Pista järgnev Pythoni skript /usr/bin/wireless-config-generate alla:

#!/usr/bin/python3

import yaml
import os
import random
import string
import crypt

WDR4300_NETWORK = """# Automatically generated, don't modify

config interface 'loopback'
    option ifname 'lo'
    option proto 'static'
    option ipaddr '127.0.0.1'
    option netmask '255.0.0.0'

config interface 'protected'
    option ifname 'eth0.3'
    option type 'bridge'
    option proto 'dhcp'

config interface 'public'
    option ifname 'eth0.4'
    option type 'bridge'
    option proto 'dhcp'

config switch
    option reset '1'
    option enable_vlan '1'
    option enable_learning '0'
    option enable_vlan4k '1'
    option name 'switch0'

# Protected wifi
config switch_vlan
    option vlan '3'
    option ports '0t 1t 2t 3t 4t 5t'
    option device 'switch0'

# Public wifi
config switch_vlan
    option vlan '4'
    option ports '0t 1t 2t 3t 4t 5t'
    option device 'switch0'
"""

SHADOW = """# Automatically generated, don't modify
root:%s:16301:0:99999:7:::
daemon:*:0:0:99999:7:::
ftp:*:0:0:99999:7:::
network:*:0:0:99999:7:::
nobody:*:0:0:99999:7:::
"""

WDR4300_SYSTEM = """# Automatically generated, don't modify

config system
        option hostname '%(HOSTNAME)s'
        option timezone '%(TIMEZONE)s'

config timeserver 'ntp'
        list server '0.openwrt.pool.ntp.org'
        list server '1.openwrt.pool.ntp.org'
        list server '2.openwrt.pool.ntp.org'
        list server '3.openwrt.pool.ntp.org'
        option enabled '1'
        option enable_server '0'

config led 'led_usb1'
        option name 'USB1'
        option sysfs 'tp-link:green:usb1'
        option trigger 'usbdev'
        option dev '1-1.1'
        option interval '50'

config led 'led_usb2'
        option name 'USB2'
        option sysfs 'tp-link:green:usb2'
        option trigger 'usbdev'
        option dev '1-1.2'
        option interval '50'

config led 'led_wlan2g'
        option name 'WLAN2G'
        option sysfs 'tp-link:blue:wlan2g'
        option trigger 'phy0tpt'
"""

WDR4300_WIRELESS = """# Automatically generated, don't modify

config wifi-device radio0
    option type mac80211
    option channel %(CHANNEL_B)s
    option hwmode 11g
    option htmode HT20
    option path 'platform/ar934x_wmac'

config wifi-iface
    option device radio0
    option network 'protected'
    option mode ap
    option encryption psk2
    option ssid '%(PROTECTED_SSID)s'
    option key '%(PROTECTED_KEY)s'

config wifi-iface
    option device radio0
    option network 'public'
    option mode ap
    option encryption none
    option ssid '%(PUBLIC_SSID)s'

config wifi-device radio1
    option path 'pci0000:00/0000:00:00.0'
    option type mac80211
    option channel %(CHANNEL_A)s
    option hwmode 11na
    option htmode HT40+
    list ht_capab LDPC
    list ht_capab SHORT-GI-20
    list ht_capab SHORT-GI-40
    list ht_capab TX-STBC
    list ht_capab RX-STBC1
    list ht_capab DSSS_CCK-40

config wifi-iface
    option device radio1
    option network 'protected'
    option mode ap
    option encryption psk2
    option ssid '%(PROTECTED_SSID)s'
    option key '%(PROTECTED_KEY)s'

config wifi-iface
    option device radio1
    option network 'public'
    option mode ap
    option encryption none
    option ssid '%(PUBLIC_SSID)s'
"""

WDR4300_RC_LOCAL = """# Automatically generated, don't modify
/etc/rc.update
exit 0
"""

WDR4300_CONFIG_SYNC = """# Automatically generated, don't modify

MAC="$(cat /sys/devices/pci0000:00/0000:00:00.0/ieee80211/phy1/macaddress)"
SOURCE="rsync://10.55.3.253:/$MAC/"
TARGET="/etc/"

# Reboot if there were changes
if [ -n "$(rsync -ricppgo $SOURCE $TARGET)" ]; then
    echo "There were configuration changes, rebooting"
    reboot
fi
"""

RSYNCD_CONF_HEADER = """# Automatically generated, don't modify
uid = nobody
gid = nogroup
log file = /var/log/rsyncd.log
use chroot = true
read only = yes
list = no
"""

if not os.path.exists("/root/.ssh"):
    os.makedirs("/root/.ssh")
if not os.path.exists("/root/.ssh/id_rsa"):
    os.system("ssh-keygen -t rsa -f /root/.ssh/id_rsa -P ''")

print("Generating configuration for AP-s in /srv/rsyncd")

with open("/etc/wireless.yml") as fh:
  with open("/etc/rsyncd.conf", "w") as rh:
    rh.write(RSYNCD_CONF_HEADER)

    g = yaml.load(fh)

    salt = ''.join([random.choice(string.ascii_letters+string.digits) for _ in range(8)])
    root_hash = crypt.crypt(g["password"], "$1$" + salt)

    for node, attribs in g["nodes"].items():
        rh.write("[%(mac)s]\npath=/srv/rsyncd/%(mac)s\n\n" % attribs)
        print("Processing AP", node, "(" + attribs["mac"] + ")")
        etc = os.path.join("/srv/rsyncd/", attribs["mac"])
        for subdir in ("dropbear", "config"):
            if not os.path.exists(os.path.join(etc, subdir)):
                os.makedirs(os.path.join(etc, subdir))
        ENV = dict(
            HOSTNAME=node,
            TIMEZONE=g.get("timezone", "UTC"),
            CHANNEL_A=attribs.get("cha"),
            CHANNEL_B=attribs.get("chb"),
            PUBLIC_SSID=g["networks"]["public"]["ssid"],
            PROTECTED_SSID=g["networks"]["protected"]["ssid"],
            PROTECTED_KEY=g["networks"]["protected"]["key"])
        with open(os.path.join(etc, "config", "wireless"), "w") as fh:
            fh.write(WDR4300_WIRELESS % ENV)
        with open(os.path.join(etc, "config", "system"), "w") as fh:
            fh.write(WDR4300_SYSTEM % ENV)
        with open(os.path.join(etc, "shadow"), "w") as fh:
            fh.write(SHADOW % root_hash)
        with open(os.path.join(etc, "config", "network"), "w") as fh:
            fh.write(WDR4300_NETWORK)
        with open(os.path.join(etc, "rc.local"), "w") as fh:
            fh.write(WDR4300_RC_LOCAL)
            os.chmod(os.path.join(etc, "rc.local"), 0o755)
        with open(os.path.join(etc, "rc.update"), "w") as fh:
            fh.write(WDR4300_CONFIG_SYNC)
            os.chmod(os.path.join(etc, "rc.update"), 0o755)
        with open(os.path.join("/root/.ssh/id_rsa.pub")) as ih:
            with open(os.path.join(etc, "dropbear", "authorized_keys"), "w") as oh:
                oh.write(ih.read())

Tee skript käivitatavaks:

chmod +x /usr/bin/wireless-config-generate

Ruuterite seadistuste genereerimiseks /srv/rsyncd alla käivita skript:

wireless-config-generate

Taaskäivita rsync teenus:

service rsyncd restart
training iptables netfilter