{ self, pkgs, hostName, config, hostConfig, ... }: with pkgs; with lib; let ports = self.lib.getOpenwrtPorts hostConfig.model; uciDeleteAll = key: '' while uci -q delete ${key}[-1]; do :; done ''; uciNetworkMgmt = ifname: '' set network.mgmt=interface set network.mgmt.ifname=${ifname} set network.mgmt.proto=static set network.mgmt.ipaddr=${config.site.net.mgmt.hosts4.${hostName}} set network.mgmt.netmask=${self.lib.netmasks.${elemAt ( builtins.split "/" config.site.net.mgmt.subnet4 ) 2}} set network.mgmt.gateway=${config.site.net.mgmt.hosts4."mgmt-gw"} set network.mgmt.ip6addr=${config.site.net.mgmt.hosts6.dn42.${hostName}} set network.mgmt.ip6gw=${config.site.net.mgmt.hosts6.dn42."mgmt-gw"} delete network.mgmt.dns add_list network.mgmt.dns={{ pillar['hosts-inet']['serv']['dnscache'] }} add_list network.mgmt.dns={{ pillar['hosts-inet6']['dn42']['serv']['dnscache'] }} ''; in '' #! ${pkgs.runtimeShell} -e ${if hostConfig.firstboot then '' ssh-keygen -R 192.168.1.1 ssh root@192.168.1.1 \ "ash -e -x" <<__SSH__ '' else '' ssh root@{{ pillar['hosts-inet']['mgmt'][hostName] }} \ "ash -e -x" <<__SSH__ ''} # Set root password echo -e '${hostConfig.password}\n${hostConfig.password}' | passwd # add ssh pubkeys ${concatMapStrings (sshPubKey: '' echo "${sshPubKey}" > /etc/dropbear/authorized_keys '') config.site.sshPubKeys} # System configuration uci batch <<__UCI__ set system.@system[0].hostName=${hostName} set dhcp.@dnsmasq[0].enabled=0 set system.@system[0].log_ip=${config.site.net.mgmt.hosts4.logging} set system.@system[0].log_proto=udp delete network.globals.ula_prefix delete network.lan delete network.wan delete network.wan6 delete wireless.default_radio0 delete wireless.default_radio1 {%- set bridges = {} %} {%- if conf.get('lan-access') %} {%- do bridges.__setitem__(conf['lan-access'], True) %} {%- endif %} {%- for path, radio in conf['radios'].items() %} {%- for ssid, ssidconf in radio['ssids'].items() %} {%- do bridges.__setitem__(ssidconf['net'], True) %} {%- endfor %} {%- endfor %} {%- if conf['model'] == 'TL-WDR4300' %} {# These models have a shared Ethernet chip for LAN/WAN and therefore need switching #} set network.@switch[0]=switch set network.@switch[0].reset=1 set network.@switch[0].enable=1 set network.@switch[0].enable_vlan=1 set network.@switch[0].name=switch0 set network.@switch_vlan[0]=switch_vlan set network.@switch_vlan[0].device='switch0' set network.@switch_vlan[0].vlan='1' set network.@switch_vlan[0].ports='0t 1t' set network.@switch_vlan[0].comment='mgmt' {%- for net, switchnum in zip(bridges.keys(), range(1, 999)) %} set network.@switch_vlan[{{ switchnum }}]=switch_vlan set network.@switch_vlan[{{ switchnum }}].device='switch0' set network.@switch_vlan[{{ switchnum }}].vlan='{{ pillar['vlans'][net] }}' {%- if conf.get('lan-access') == net %} set network.@switch_vlan[{{ switchnum }}].ports='0t 1t 2 3 4 5' {%- else %} set network.@switch_vlan[{{ switchnum }}].ports='0t 1t' {%- endif %} set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}' {%- endfor %} ${uciNetworkMgmt "eth0.1"} {%- for net in bridges.keys() %} set network.{{ net }}=interface set network.{{ net }}.type=bridge set network.{{ net }}.proto=static set network.{{ net }}.ifname='eth0.{{ pillar['vlans'][net] }}' {%- endfor %} {%- elif conf['model'] == 'TL-WR1043ND' %} {# These models have a shared Ethernet chip with separate CPU ports for LAN/WAN and therefore need switching #} set network.@switch[0]=switch set network.@switch[0].reset=1 set network.@switch[0].enable=1 set network.@switch[0].enable_vlan=1 set network.@switch[0].name=switch0 set network.@switch_vlan[0]=switch_vlan set network.@switch_vlan[0].device='switch0' set network.@switch_vlan[0].vlan='1' set network.@switch_vlan[0].ports='5t 6t' set network.@switch_vlan[0].comment='mgmt' {%- for net, switchnum in zip(bridges.keys(), range(1, 999)) %} set network.@switch_vlan[{{ switchnum }}]=switch_vlan set network.@switch_vlan[{{ switchnum }}].device='switch0' set network.@switch_vlan[{{ switchnum }}].vlan='{{ pillar['vlans'][net] }}' # 0: eth1; 1-4: LAN ports in reverse; 5: WAN port; 6: eth0 {%- if conf.get('lan-access') == net %} set network.@switch_vlan[{{ switchnum }}].ports='0 1 2 3 4 5t' {%- else %} set network.@switch_vlan[{{ switchnum }}].ports='5t 6t' {%- endif %} set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}' {%- endfor %} ${uciNetworkMgmt "eth0.1"} {%- for net in bridges.keys() %} set network.{{ net }}=interface set network.{{ net }}.type=bridge set network.{{ net }}.proto=static {%- if conf.get('lan-access') == net %} set network.{{ net }}.ifname='eth1' {%- else %} set network.{{ net }}.ifname='eth0.{{ pillar['vlans'][net] }}' {%- endif %} {%- endfor %} {%- elif conf['model'] == 'TL-Archer-C7v2' %} {# These models have a shared Ethernet chip with separate CPU ports for LAN/WAN and therefore need switching #} set network.@switch[0]=switch set network.@switch[0].reset=1 set network.@switch[0].enable=1 set network.@switch[0].enable_vlan=1 set network.@switch[0].name=switch0 set network.@switch_vlan[0]=switch_vlan set network.@switch_vlan[0].device='switch0' set network.@switch_vlan[0].vlan='1' set network.@switch_vlan[0].ports='1t 6t' set network.@switch_vlan[0].comment='mgmt' {%- for net, switchnum in zip(bridges.keys(), range(1, 999)) %} set network.@switch_vlan[{{ switchnum }}]=switch_vlan set network.@switch_vlan[{{ switchnum }}].device='switch0' set network.@switch_vlan[{{ switchnum }}].vlan='{{ pillar['vlans'][net] }}' # 0: eth1; 1: WAN port; 2-5: LAN ports; 6: eth0 {%- if conf.get('lan-access') == net %} set network.@switch_vlan[{{ switchnum }}].ports='0 1t 2 3 4 5' {%- else %} set network.@switch_vlan[{{ switchnum }}].ports='1t 6t' {%- endif %} set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}' {%- endfor %} ${uciNetworkMgmt "eth0.1"} {%- for net in bridges.keys() %} set network.{{ net }}=interface set network.{{ net }}.type=bridge set network.{{ net }}.proto=static {%- if conf.get('lan-access') == net %} set network.{{ net }}.ifname='eth1' {%- else %} set network.{{ net }}.ifname='eth0.{{ pillar['vlans'][net] }}' {%- endif %} {%- endfor %} {%- elif conf['model'] == 'TL-Archer-C7v4' or conf['model'] == 'TL-Archer-C7v5' %} set network.@switch[0]=switch set network.@switch[0].reset=1 set network.@switch[0].enable=1 set network.@switch[0].enable_vlan=1 set network.@switch[0].name=switch0 set network.@switch_vlan[0]=switch_vlan set network.@switch_vlan[0].device='switch0' set network.@switch_vlan[0].vlan='1' set network.@switch_vlan[0].ports='0t 1t' set network.@switch_vlan[0].comment='mgmt' {%- for net, switchnum in zip(bridges.keys(), range(1, 999)) %} set network.@switch_vlan[{{ switchnum }}]=switch_vlan set network.@switch_vlan[{{ switchnum }}].device='switch0' set network.@switch_vlan[{{ switchnum }}].vlan='{{ pillar['vlans'][net] }}' # 0: eth0; 1: WAN port; 2-5: LAN ports {%- if conf.get('lan-access') == net %} set network.@switch_vlan[{{ switchnum }}].ports='0t 1t 2 3 4 5' {%- else %} set network.@switch_vlan[{{ switchnum }}].ports='0t 1t' {%- endif %} set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}' {%- endfor %} ${uciNetworkMgmt "eth0.1"} {%- for net in bridges.keys() %} set network.{{ net }}=interface set network.{{ net }}.type=bridge set network.{{ net }}.proto=static set network.{{ net }}.ifname='eth0.{{ pillar['vlans'][net] }}' {%- endfor %} {%- elif conf['model'] == 'TL-WR1043NDv4' or conf['model'] == 'TL-WR1043NDv5' %} set network.@switch[0]=switch set network.@switch[0].reset=1 set network.@switch[0].enable=1 set network.@switch[0].enable_vlan=1 set network.@switch[0].name=switch0 set network.@switch_vlan[0]=switch_vlan set network.@switch_vlan[0].device='switch0' set network.@switch_vlan[0].vlan='1' set network.@switch_vlan[0].ports='0t 5t' set network.@switch_vlan[0].comment='mgmt' {%- for net, switchnum in zip(bridges.keys(), range(1, 999)) %} set network.@switch_vlan[{{ switchnum }}]=switch_vlan set network.@switch_vlan[{{ switchnum }}].device='switch0' set network.@switch_vlan[{{ switchnum }}].vlan='{{ pillar['vlans'][net] }}' # 0: eth0; 1-4: LAN ports; 5: WAN port {%- if conf.get('lan-access') == net %} set network.@switch_vlan[{{ switchnum }}].ports='0t 1 2 3 4 5t' {%- else %} set network.@switch_vlan[{{ switchnum }}].ports='0t 5t' {%- endif %} set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}' {%- endfor %} ${uciNetworkMgmt "eth0.1"} {%- for net in bridges.keys() %} set network.{{ net }}=interface set network.{{ net }}.type=bridge set network.{{ net }}.proto=static set network.{{ net }}.ifname='eth0.{{ pillar['vlans'][net] }}' {%- endfor %} {%- elif conf['model'] == 'TL-WR841Nv8' %} {# Like v9 but with eth0/1 switched #} set network.@switch[0].reset=1 set network.@switch[0].enable=1 set network.@switch[0].enable_vlan=0 ${uciNetworkMgmt "eth0.1"} {%- for net in bridges.keys() %} set network.{{ net }}=interface set network.{{ net }}.type=bridge set network.{{ net }}.proto=static {# Add WAN VLAN to bridge #} {%- set ports = ['eth0.' ~ pillar['vlans'][net]] %} {# Add LAN ports to bridge #} {%- if conf.get('lan-access') == net %} {%- do ports.append('eth1') %} {%- endif %} set network.{{ net }}.ifname='{{ ' '.join(ports) }}' {%- endfor %} {%- elif conf['model'] == 'TL-WR740Nv4' %} {# Separate eth0/1 interfaces for LAN/WAN #} {# eth0 - Port 0: eth0, Port 2: LAN1, Port 3: LAN2, Port 4: LAN3, Port 1: LAN4 #} {# eth1 - WAN #} set network.@switch[0].reset=1 set network.@switch[0].enable=1 set network.@switch[0].enable_vlan=0 ${uciNetworkMgmt "eth1.1"} {%- for net in bridges.keys() %} set network.{{ net }}=interface set network.{{ net }}.type=bridge set network.{{ net }}.proto=static {# Add WAN VLAN to bridge #} {%- set ports = ['eth1.' ~ pillar['vlans'][net]] %} {# Add LAN ports to bridge #} {%- if conf.get('lan-access') == net %} {%- do ports.append('eth0') %} {%- endif %} set network.{{ net }}.ifname='{{ ' '.join(ports) }}' {%- endfor %} {%- elif conf['model'] == 'TL-WA901NDv3' or conf['model'] == 'Ubnt-UniFi-AP-AC-LR' %} {# Only eth0 exists, no switch #} ${uciNetworkMgmt "eth0.1"} {%- for net in bridges.keys() %} set network.{{ net }}=interface set network.{{ net }}.type=bridge set network.{{ net }}.proto=static {# Add WAN VLAN to bridge #} set network.{{ net }}.ifname='{{ 'eth0.' ~ pillar['vlans'][net] }}' {%- endfor %} {%- elif conf['model'] == 'Ubnt-UAP-nanoHD' %} {# no switch, eth0 exists but is not usable, using "lan" instead #} ${uciNetworkMgmt "lan.1"} {%- for net in bridges.keys() %} set network.{{ net }}=interface set network.{{ net }}.type=bridge set network.{{ net }}.proto=static {# Add WAN VLAN to bridge #} set network.{{ net }}.ifname='{{ 'lan.' ~ pillar['vlans'][net] }}' {%- endfor %} {%- elif conf['model'] == 'DIR-615H1' or conf['model'] == 'DIR-615D4' %} {# All DIR-615 share the same port layout #} delete network.lan_dev delete network.wan_dev {# switch is cpu port 6, wan:cpu port 4, lan port 1 is cpu port 3, lan port 2 is 2 etc #} set network.@switch[0]=switch set network.@switch[0].reset=1 set network.@switch[0].enable=1 set network.@switch[0].enable_vlan=1 set network.@switch[0].name=switch0 set network.@switch_vlan[0]=switch_vlan set network.@switch_vlan[0].device='switch0' set network.@switch_vlan[0].vlan='1' set network.@switch_vlan[0].ports='4t 6t' set network.@switch_vlan[0].comment='mgmt' {%- for net, switchnum in zip(bridges.keys(), range(1, 999)) %} set network.@switch_vlan[{{ switchnum }}]=switch_vlan set network.@switch_vlan[{{ switchnum }}].device='switch0' set network.@switch_vlan[{{ switchnum }}].vlan='{{ pillar['vlans'][net] }}' {%- if conf.get('lan-access') == net %} set network.@switch_vlan[{{ switchnum }}].ports='0 1 2 3 4t 6t' {%- else %} set network.@switch_vlan[{{ switchnum }}].ports='4t 6t' {%- endif %} set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}' {%- endfor %} ${uciNetworkMgmt "eth0.1"} {%- for net in bridges.keys() %} set network.{{ net }}=interface set network.{{ net }}.type=bridge set network.{{ net }}.proto=static #TODO: this should consider lan-access set network.{{ net }}.ifname='eth0.{{ pillar['vlans'][net] }}' {%- endfor %} {%- else %} {# All other models may have separate Ethernet chips for LAN/WAN #} set network.@switch[0].reset=1 set network.@switch[0].enable=1 set network.@switch[0].enable_vlan=0 ${uciNetworkMgmt "eth1.1"} {%- for net in bridges.keys() %} set network.{{ net }}=interface set network.{{ net }}.type=bridge set network.{{ net }}.proto=static {# Add WAN VLAN to bridge #} {%- set ports = ['eth1.' ~ pillar['vlans'][net]] %} {# Add LAN ports to bridge #} {%- if conf.get('lan-access') == net %} {%- do ports.append('eth0') %} {%- endif %} set network.{{ net }}.ifname='{{ ' '.join(ports) }}' {%- endfor %} {%- endif %} ${uciDeleteAll "wireless.@wifi"} ${concatStrings (imap0 (index: path: let radioConfig = hostConfig.wifi.${path}; ifPrefix = if radioConfig.channel < 15 then "wlan2" else "wlan5"; in '' set wireless.radio${toString index}=wifi-device set wireless.radio${toString index}=wifi-device set wireless.radio${toString index}.type=mac80211 set wireless.radio${toString index}.country=DE set wireless.radio${toString index}.channel=${toString radioConfig.channel} set wireless.radio${toString index}.path=${path} set wireless.radio${toString index}.htmode=${radioConfig.htmode} set wireless.radio${toString index}.noscan=1 delete wireless.radio${toString index}.disabled ${concatMapStrings (ssid: let ssidConfig = radioConfig.ssids.${ssid}; in '' add wireless wifi set wireless.@wifi-iface[-1].ifname=${ifPrefix}-${ssidConfig.net} set wireless.@wifi-iface[-1].device=radio${toString index} set wireless.@wifi-iface[-1].ssid='${ssid}' set wireless.@wifi-iface[-1].mode=ap set wireless.@wifi-iface[-1].network=${ssidConfig.net} set wireless.@wifi-iface[-1].mcast_rate=18000 ${if (ssidConfig.psk != null) then '' set wireless.@wifi-iface[-1].encryption=psk2 set wireless.@wifi-iface[-1].key='${ssidConfig.psk}' '' else '' set wireless.@wifi-iface[-1].encryption=none delete wireless.@wifi-iface[-1].key ''} '' ) (builtins.attrNames radioConfig.ssids)} '') (builtins.attrNames hostConfig.wifi))} commit __UCI__ # Cronjob that makes sure WiFi is only visible when server with all # the gateways is reachable cat >/etc/crontabs/root <<__CRON__ * * * * * /usr/sbin/wifi-on-link.sh __CRON__ cat >/usr/sbin/wifi-on-link.sh <<__SH__ #!/bin/sh if (ping -c 1 -W 3 {{ pillar['hosts-inet']['mgmt']['mgmt-gw'] }}) ; then REACHABLE=y else REACHABLE=n fi if [ "\\\$(cat /sys/class/net/wlan2-pub/operstate)" == "up" ] ; then UP=y else UP=n fi {%- if conf.get("error-led") %} ERROR_LED=/sys/class/leds/{{ conf["error-led"] }}/brightness [ \\\$REACHABLE = y ] && echo 0 > \\\$ERROR_LED [ \\\$REACHABLE = n ] && echo 1 > \\\$ERROR_LED {%- endif %} [ \\\$REACHABLE = y ] && [ \\\$UP = n ] && wifi up [ \\\$REACHABLE = n ] && [ \\\$UP = y ] && wifi down exit 0 __SH__ chmod a+rx /usr/sbin/wifi-on-link.sh /etc/init.d/cron restart for svc in dnsmasq uhttpd ; do rm /etc/rc.d/*\$svc /etc/init.d/\$svc stop done ${lib.optionalString hostConfig.firstboot "reboot"} __SSH__ echo "Base configuration done \\o/" echo "Later run: `dirname $0`/ap_install_collectd.sh ${config.site.net.mgmt.hosts4.${hostName}}" ''