Gluon und die WAN-MAC

Moin Folks,

ich brauche mal ein Meinungsbild …

»Gluon«, unsere Firmware-Basis, mach immer wieder neue Sperenzchen mit der Hardware- (Ethernet-) Adresse des WAN-Inferfaces (so vorhanden). Wir finden ja das Umstöpseln des Kabels zwischen Normal- und Config-Mode doof, weshalb bei uns das ggf. auch eher aufstöst als in anderen Communities, die wirklich noch die Kabel umstecken, wollen sie einen Knoten auf dem Dach umkonfigurieren …

Anyway: in der letzten Firmware haben wir ein Flag eingeführt, welches sicherstellen sollte, daß sich die Adresse des WAN-Interfaces sich ›niemals nicht‹ ändert. Leider ist die Funktion dort broken, im Config-Mode hat der Knoten auch dann einen andere Adresse als im Wirkmodus — die Frage ist, wollen wir das ändern?

Derzeit setzt Gluon im Config-Mode jedenfalls die »zentrale MAC« (== LAN-Interface bei Geräten mit >1 Ethernet), und die aktuelle Version unserer Firmware versucht, dies zu kontern (und setzt die »echte« WAN-MAC, die aber, s. o., nicht die MAC ist, die der Knoten im Config-Mode hat).

uci_set network setup ifname "$(lua -e 'print(require("gluon.sysconfig").setup_ifname)')"
uci_set network setup macaddr "$(lua -e 'print(require("gluon.sysconfig").primary_mac)')"

Es gibt nun drei Möglichkeiten:

  • Alles lassen, wie es ist: im Config-Mode hat das WAN-IF die MAC des LANs, im Normalmodus eine »Gluon-generierte« (v2016.2.x: basierend auf dem md5-Hash der primären MAC)

  • Bei den Knoten, die »don’t modify my WAN« gesetzt haben: Rückportierung des v2015.1-Vorgehens. WAN hat im Config-Mode weiter andere MAC als im normalen Modus

  • irgendwie Config- und Normalmodus einfangen (entweder generierte MAC auch im Config-Mode oder aber native »WAN«-MAC ›immer‹)

Comments?

Prinzipiell ist das ja garnicht das Problem, denn der jenige der die MACs filtert um die Zugang zu kontrollieren weis eigentlich was er mit den Config Mode macht. Das Problem was ich halt sehe, das gefühlt nach jeden zweiten oder dritten Firmware Update wieder eine andere Basis benutzt wird für die MAC und dann im normalen Moduse es wieder eine andere ist.

Bei denen wo es gesetzt ist muss eigentlich die aktuell gesetzte MAC in der Config gespeichert werden und dann gesetzt werden. (Wenn man das macht kann man auch gleichzeitig ein Feld machen mit der man die MAC mit Hand eintragen könnte).

… DAS ist das Problem, ack.

Und bei der Freischaltung ist es halt doof, wenn die Freischaltung (wie z. B. in Autohäusern oder im Holiday Inn) extern vorgenommen wird — und die MAC sich beim FW-Update und/oder für den Config-Mode ändert (im letzteren Fall hat der Knoten dann keinen Internetzugang mehr und der Config-Mode ist nicht mehr funktional). Deshalb brauchen wir an sich eine finale Lösung …

Ich hole mal ein bißchen aus: Die Ursache des Problems ist primär, daß wir bei Geräten mit nur ein bis zwei MAC-Adressen effektiv bis zu acht brauchen. In Gluon v2014.3 und .4 wurde die MAC einfach auf Basis der “Haupt-MAC” zerwürfelt — der Grund für Änderungen zwischen 2014.3 und .4 waren auftretende doppelte MACs, nachdem Leute größere Anzahlen von Routern für das gleiche Mesh kauften. Dank der fortlaufenden Ausgangs-MAC-Adressen ging’s in die Hose, da nur das vorvorletzte und das letzte Byte geändert wurden — für v2014.4 wurde daher das Ändern in vordere Bytes verlegt.
In unserer 0.7.4er FW, die auf v2015.1 basiert, habe ich die beiden Routinen eingebaut und anhand des neuen Flags wan_mac_static ggf. die alte Version für die Erzeugung der WAN-Adresse aufgerufen:

-- Generates a (hopefully) unique MAC address
-- The first parameter defines the function and the second
-- parameter an ID to add to the MAC address
-- Functions and IDs defined so far:
-- (1, 0): WAN (for mesh-on-WAN)
-- (1, 1): LAN (for mesh-on-LAN)
-- (2, n): client interface for the n'th radio
-- (3, n): adhoc interface for n'th radio
-- (4, 0): mesh VPN
-- (5, n): possible additional client interface for the n'th radio
function generate_mac_2014_4(f, i)
  local m1, m2, m3, m4, m5, m6 = string.match(sysconfig.primary_mac, '(%x%x):(%x%x):(%x%x):(%x%x):(%x%x):(%x%x)')
  m1 = nixio.bit.bor(tonumber(m1, 16), 0x02)
  m2 = (tonumber(m2, 16)+f) % 0x100
  m3 = (tonumber(m3, 16)+i) % 0x100

  return string.format('%02x:%02x:%02x:%s:%s:%s', m1, m2, m3, m4, m5, m6)
end

-- fix up duplicate mac addresses
function generate_mac_2014_3(f, i)
  local m1, m2, m3, m4, m5, m6 = string.match(sysconfig.primary_mac, '(%x%x):(%x%x):(%x%x):(%x%x):(%x%x):(%x%x)')
  m1 = nixio.bit.bor(tonumber(m1, 16), 0x02)
  m4 = (tonumber(m4, 16)+1) % 0x100
  m6 = (tonumber(m6, 16)+1) % 0x100

  return string.format('%02x:%s:%s:%02x:%s:%02x', m1, m2, m3, m4, m5, m6)
 end

Nun, mit Gluon v2016.1 und der Unterstützung zusäztlicher Hardware, gibt es neue Probleme:

Many devices don’t have enough unique MAC addresses assigned by the vendor (in batman-adv, each mesh interface needs an own MAC address that must be unique mesh-wide).

Gluon tries to solve this issue by using a hash of the primary MAC address as a 45 bit MAC address prefix. The resulting 8 addresses are used as follows:

0: client0; WAN
1: mesh0
2: ibss0
3: wan_radio0 (private WLAN); batman-adv primary address
4: client1; LAN
5: mesh1
6: ibss1
7: wan_radio1 (private WLAN); mesh VPN

Konkret sieht die Funktion jetzt so aus (Version für unsere 0.7.9/0.8.0) — man beachte den Kommentar zu den ersten 45 Bit der 48 Bit der MAC-Adresse …

function generate_mac(i)
  if i > 7 or i < 0 then return nil end -- max allowed id (0b111)

  local hashed = string.sub(hash.md5(sysconfig.primary_mac), 0, 12)
  local m1, m2, m3, m4, m5, m6 = string.match(hashed, '(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)')

  if i == 0 then
    if sysconfig.wan_ifname then
      return lutil.trim(fs.readfile('/sys/class/net/' .. sysconfig.wan_ifname .. '/address'))
    end
  end

  m1 = tonumber(m1, 16)
  m6 = tonumber(m6, 16)

  m1 = nixio.bit.bor(m1, 0x02)  -- set locally administered bit
  m1 = nixio.bit.band(m1, 0xFE) -- unset the multicast bit

  -- It's necessary that the first 45 bits of the MAC address don't
  -- vary on a single hardware interface, since some chips are using
  -- a hardware MAC filter. (e.g 'rt305x')

  m6 = nixio.bit.band(m6, 0xF8) -- zero the last three bits (space needed for counting)
  m6 = m6 + i                   -- add virtual interface id

  return string.format('%02x:%s:%s:%s:%s:%02x', m1, m2, m3, m4, m5, m6)
end

Mit anderen Worten: effektiv bleibt nur die Option, die MAC erzeugen zu lassen, und die identische MAC bei Setup- und Normalmodus zu nutzen. DANN kann man diese MAC einmalig freischalten und den Knoten in beiden Modi nutzen. Obiges Modell klingt auch hinreichend zukunftssicher, daß es hoffentlich die letzte MAC-Erzeugungs-Variante ist.

Ja, so dachte ich auch mal; aber, siehe aktuelle Entwicklungen, nicht jede Hardware schluckt offensichtlich jede Adresse, und somit erscheint es mir zielführender, in Config- und Normalmodus die gleiche, generierte, Adresse zu verwenden.
In unserem Ablauf müßte das die sinnvollste Variante sein: da wir immer über WAN gehen, haben wir dann genau 1 MAC freizuschalten.
Ein Knoten mit FFGT-FW ändert somit seine MAC auf WAN nicht mehr, und das Prozedere, einen Router initial mit der FFGT-FW zu versorgen, hat i. d. R. nix mit LAN-DHCP zu tun.

Also ich kann am Besten mit einer Variante leben, die am wenigsten Hickhack und Aufwand in der Firmware erzeugt und vielleicht auch von den größeren Communities bevorzugt wird.

Config- und Normal-Mode am WAN-Port ist schon begrüßenswert. Und da dann die selbe (erzeugte) Mac-Adresse zu haben ist nett, für meine Zwecke aber nicht extrem wichtig. Aber ich kann sehr gut verstehen, dass es bei externer Freischaltung an Firewalls nervt…

Zur Hardware-Mac: Kann denn nicht zumindest am WAN-Port eine/die echte, vorhandene Hardware-MAC verwendet werden? Und der Rest wird gewürfelt - oder kommt es genau deswegen zu Kollisionen?

lg outlawx

Wie schon geschrieben: Früher hat man die MACs an Byte 4 und 6 von 6 (11:22:33:44:55:66) geändert — genauer: Byte 4 und Byte 6 um je 1 erhöht für “die” zweite Adresse für’s Mesh. Da kam es bei größeren zeitnahen Ausbauten wohl zu Überschneidungen. Also wechselte man auf die Bytes 2 und 3 — nur um festzustellen, daß neu unterstützte Hardware (Mediatek) nun DAS wieder doof findet. Ergo wandelt man die HW-MAC nun in einen md5-Hashwert und ändert von jenen 48 Bit (6 Bytes) nur die letzten 3.

An sich wäre es wohl an der Zeit, mit der kommenden FFGT-FW die WAN-MAC im Config-Mode zu speichern und zukünftig immer diese zu setzen, wie schon vorgeschlagen wurde.
Damit wären wir für bestehende HW (bei sysupgrades) auf der sicheren Seite, und auch für zukünftige. Denn, da wir eher kein Early Adopter sind, sollten MAC-Erstellungsprobleme bekannt sein, bis wir auf Gluon v2017.1 oder neuer gehen. Und wenn wir dort die WAN-MAC bei Einrichtung ebenfalls speichern, stören uns spätere Änderungen des Algorithmus’ nicht.

Sprich: noch einmal durch das Tal der Tränen, sprich: WAN-MAC-Änderung durch FW-Upgrade, aber danach dann wirklich nicht mehr. (Edge case: komplett neu flashen wäre dann doof; Config-Mode allerdings ginge.)

Übersehe ich was? Ist das ein gangbarer Kompromiß?

OT: Das wäre natürlich schon schick wenn endlich preiswert Dual-Band mit MTK möglich wäre. Habe schon einen kleinen Stapel zu liegen, leider alles weiterhin halbgar. Ist wie mit den Android-Telefonen: MTK vs QCA. Und bei den Herstellern ist MTK nicht beliebt, sonder einfach nur sch***e billig im Einkauf. Auch bisschen wie bei AMD und Intel. Und so dreht sich das im Kreis und ist einfach nur traurig…

Ok, das meinte ich :wink: Andererseits halten sich – für mich: – erstaunlicherweise Linux-basierte WLAN-Router trotz der höheren Anforderungen (RAM, Flash) nach wie vor im Markt, und den 841er gab’s jüngst für irgendwas bei 13,-- zu kaufen. Klar, eine Million mal 1 Dollar sind auch eine Million Dollar, aber ganz so knapp scheint nicht mehr kalkuliert werden zu müssen?
Mir geht’s auch weniger um »preiswertes Dual-Band«, sondern mehr um eine breitere Auswahlbasis, daher fände ich neben Qualcomm/Atheros eine weitere – meshfähige, und sei es »nur« auf Basis von 802.11s – Plattform zu haben, schon wichtig. (Andererseits, AVM ist auch nur selten auf anderen Hersteller/Plattformen ausgewichen und hat es i. d. R. auch bereuen müssen — siehe 7390. Langfristig macht es schein’s tatsächlich Sinn, bei den Herstellern zu bleiben, »die es einfach können« …) Aber ich schweife ab.

Hallo Kai,

mir wäre es lieb, wenn die MAC statisch ist - und so, wie sie auf der Verpackung steht. :wink:

Ich muss zwar die MACs nicht “extern” freischalten lassen, aber “Autoupgrade” müsste ich bei ständigem MAC-Wechsel dann doch ausschalten. Andere (kleinere) Verwaltungen oder solche mit staalichem/kommunalen Dienstleistern (wird zukünftig “verpflichtend”) können diese Änderungen dann nur gegen Geld durchführen lassen oder werden Freifunk nicht mehr über ihre Netze routen.

Je weniger Änderungen und Umstecken … umso besser. :+1:

cul8er
Matthias

Wie schon dargelegt, DAS ist latent … schwierig, weil Sonderfälle zu beachten (welche HW haben wir denn hier, und von welcher weiß ich, daß Kombination X mit Y geht). Und auf dem 1043v4, den ich gleich verarzten werde, steht auch keine MAC »auf der Verpackung« :wink: Unten drauf steht … eine, bei WAN, LAN & WiFi eine relativ knappe Info :wink:

Deshalb diskutieren wir ja hier :wink: Ich muß in meinem Netz auch jene MAC freischalten (selbst gewähltes Leid, aber auch ein bißchen gefühlte Sicherheit; selbst wenn ein Kind die WPA-Phrase weitergäbe, zumindest gibt’s keine v4-IP — und mit v6-only kommt zum Glück noch kaum ein Gerät klar ;)) und daher nervt es mich gerade massiv, daß Gluon schon wieder den Mechanismus geändert.
Allerdings: dies ist nun mal learning-by-doing, und immerhin treibt Gluon wohl den Großteil der 10.000+ Freifunk-Knoten in Deutschland an … Und diesmal kann ich den nochmaligen Wechsel nachvollziehen (was nützt eine stabile MAC, wenn die Hardware diese verwirft?) und bin guter Dinge, daß diese Variante bestand haben könnte.

Second that; insbesondere, wenn man die Knoten fernadministriert. Also Interims-Firmware für alle 0.7.4er Kisten, die die aktuelle WAN-MAC (konkret: die von br-wan) in der Config speichert, wo FW ab 0.7.9 sie dann ausliest und übernimmt für Config- und Normalmode? Das sollte für die Zukunft uns das Thema vom Hals halten …

Das mit dem nicht schlucken von nicht allen MAC Adressen sollte doch auch kein Problem sein wenn die MAC bei bestehenden Geräten in der Config mit abgespeichert wird. Wenn keine MAC in der Config hinterlegt ist, z.B. bei Neugeräten kann dann ja nach dem neuen Verfahren die MAC generiert werden. So sollten doch alt Geräte keine neue bekommen und Neugeräte nicht mit dem alten Problem betroffen sein.

Richtig? So würde ich es machen.

Das mit dem nicht schlucken von nicht allen MAC Adressen sollte doch auch kein Problem sein wenn die MAC bei bestehenden Geräten in der Config mit abgespeichert wird. Wenn keine MAC in der Config hinterlegt ist, z.B. bei Neugeräten kann dann ja nach dem neuen Verfahren die MAC generiert werden. So sollten doch alt Geräte keine neue bekommen und Neugeräte nicht mit dem alten Problem betroffen sein.

Richtig? So würde ich es machen.

Genau das ist die aktuelle Überlegung. Problem nur: von 0.7.4/0.7.5 auf 0.8.x (bzw. 0.7.9 als 0.8-Beta) ändert sich schon die WAN-MAC, und bislang hat keine Firmware die benutzte WAN-MAC weggeschrieben. Für 0.7.4 könnte ich ein Vor-Update-Update rausschicken, welches die atuelle MAC in die Config schreibt, und in 0.7.9/0.8.x würde diese dann in Config- und Normalmodus benutzt (bzw., falls nicht vorhanden, die verwendete ebenfalls für spätere Nutzung weggeschrieben).

Problem nur: die Entwicklungsversion von 0.7.4 ist ca. 100 Builds neuer als die zuletzt als Stable ausgerollte — und für Knoten auf 0.5.x (2) und 0.7.5 ("'n paar") geht das nicht (keine Build-Umgebung mehr).

Aber es scheint die beste aller schlechten Lösungen zu sein :wink:

Ja,

und die Frage ist wie viel von den alten Knoten währen betroffen von einen Problem durch MAC Adressänderung?

Das ist unbekannt. Ich weiß von mind. 1 Autohaus, ggf. Ketten (Bäckereien, Schenke, …) und Verwaltungen, IT-affine Privatleute, …

Die 0.7.5 gerade gezählt sind 56 schon arg viel; hmm …

Aber das vor Update für 0.7.4 währe kein Problem meinst du.

Naja, es stellte sich heraus, eine Kiste bei Hetzner ist völlig überlastet (daher auch die Ausfälle an der Müritz heute morgen und die sporadische Unerreichbarkeit des Forums), halt die, die das Build-System “für 0.7.4” beherbergt :frowning:

(2 GB-VMs fressen 6 GB RAM, das ist “etwas” doof, wenn man die 16 GB anhand des zugewiesenen Speichers verplant hat => Server hat 6-8 GB auf Platte ausgelagert, auf zwei IDE-Platten im Software-RAID-1, um genau zu sein, entsprechend rottig ist die Performance :frowning: Wohl mal Zeit für Kernel- bzw. gar Distributionsupdate dort — nach 539 Tagen auch an der Zeit.)

Ja, 0.7.5 war die Zwischenversion für den 841v10 (+ v11?). Basiert, wie die kommende 0.8, auf OpenWRT Chaos Calmer (statt, wie 0.7.4, auf OpenWRT Barrier Breaker, der Vorgängerversion). Sysupgrade von neuerer auf ältere OpenWRT-Basis geht nicht, daher blieb 0.7.5 stehen.

0.7.4~215 hat entsprechende Patches drin, die (auf 0.7.9er Testknoten) funktionierten:

root@33332-Testknoten-81ec:~# uci show network.wan
network.wan=interface
network.wan.ifname='eth1'
network.wan.multicast_querier='0'
network.wan.peerdns='0'
network.wan.auto='1'
network.wan.type='bridge'
network.wan.proto='dhcp'
network.wan.macaddr='e8:94:f6:90:81:ed'
root@33332-Testknoten-81ec:~# echo $(lua -e 'print(require("gluon.util").generate_mac(0))')
7e:1d:c4:3c:df:10
root@33332-Testknoten-81ec:~# /lib/gluon/upgrade/999-save-wan-mac.sh
root@33332-Testknoten-81ec:~# echo $(lua -e 'print(require("gluon.util").generate_mac(0))')
e8:94:f6:90:81:ed

Wäre toll, wenn jemand das mal ausprobieren könnte mit einem 0.7.4er Knoten, der die stable drauf hat. Nach dem sysugrade sollten dann in Normal- wie Config-Mode nur noch die zum Installationszeitpunkt generierte WAN-MAC verwendet werden, ebenso sollte diese nach einem Upgrade auf 0.7.9 identisch bleiben. (Und, Kür, eine andere sein als bei Neuinstallation jenes Knotens mit 0.7.9; aber auch dort sollte die einmal generierte in Config- und Normalmode nicht mehr wechseln.)

Werde es vermutlich Donnerstag erst richtig durchtesten können.

Gibt es überhaupt eben Befehl um ein spezielles Image einzuspielen? Oder muss man immer über das Web Interface im Configuration Mode gehen?

Gibt es überhaupt eben Befehl um ein spezielles Image einzuspielen? Oder muss man immer über das Web Interface im Configuration Mode gehen?

Klar. Auf den Knoten per ssh gehen und dann:

cd /tmp
wget http://firmware.4830.org/rawhide/sysupgrade/gluon-ffgt-VERSION-$(lua -e 'print(require("platform_info").get_image_name())')-sysupgrade.bin
sysupgrade -v gluon-<TAB>

“VERSION” durch die Wunschversion ersetzen, also z. B. “0.7.4~215”. Alternativ direkt den kompletten Pfad für wget von firmware.4830.org per cut&paste übernehmen :wink:

Habe gerade einen Knoten akualisisiert, der schon die 0.7.4~210 drauf hate. Sollte doch prinzipell auch kein Problem sein oder?

Update lief druch, MAC ist auch geblieben. habe dann per SSH in den Config Mode gebootet. Hier hat er mich dann ausgesperrt. Kann ihn nicht mehr anpingen, kein SSH und kein Webinterface, scheinbar auch laut FritzBox eine andere MAC genommen.

Siehe

Vorher:
PC-192-168-XXX-167 192.168.XXX.167 C4:6E:1F:7A:AC:4D

Nachher
PC-192-168-XXX-135 192.168.XXX.135 C6:6F:1F:63:0E:F0

weiter kann ich gerade leider nicht schauen, da ich zu dem Standort von hier aus nur einen VPN Zugang habe.

Was zu den Knoten noch zu sagen ist, er hat die Option gesetzt LAN Ports mit WAN Ports bridgen. Evtl. zickt deshalb der Config Mode. (Evtl. könnte man einen automatischen Reboot einbauen im Configmode nach 1 Std.; länger sollte man ihn ja eigentlich nicht brauchen)


OK, war mal mutig, habe den zweiten Knoten der kein Bridge zwischen WAN und LAN Ports hat auch geupdatet und im Config Mode gesetzt. Selbe spielchen. In der FritzBox gibt es eine andere MAC und IP zu sehen, wieder C4:… Drauf kommen tue ich auch wieder nicht. Da muss ich morgen wohl mal rebooten.

Was noch interessant ist,

echo $(lua -e ‘print(require(“gluon.util”).generate_mac(0))’)
lua: error loading module ‘gluon.util’ from file ‘/usr/lib/lua/gluon/util.lua’:
/usr/lib/lua/gluon/util.lua:73: ‘end’ expected (to close ‘if’ at line 71) near 'if’
stack traceback:
[C]: ?
[C]: in function ‘require’
(command line):1: in main chunk
[C]: ?

Habe den Befehl von dir direkt nach dem Update eingeben. Da hätte ja eigentlich eine MAC ausgegeben werden müssen, oder?

Yepp. Und da die Funktion im Config-Mode aufgerufen wird, geht’s da evtl. nicht weiter.

Fsck, im 0.7.4er Tree fehlte tatsächlich ein “end”, das im 0.7.9er da ist :frowning: Sorry.