<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://leo.leung.xyz/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=136.159.160.123</id>
	<title>Leo&#039;s Notes - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://leo.leung.xyz/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=136.159.160.123"/>
	<link rel="alternate" type="text/html" href="https://leo.leung.xyz/wiki/Special:Contributions/136.159.160.123"/>
	<updated>2026-10-08T02:46:48Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://leo.leung.xyz/wiki/index.php?title=NixOS&amp;diff=7357</id>
		<title>NixOS</title>
		<link rel="alternate" type="text/html" href="https://leo.leung.xyz/wiki/index.php?title=NixOS&amp;diff=7357"/>
		<updated>2023-09-18T17:40:53Z</updated>

		<summary type="html">&lt;p&gt;136.159.160.123: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NixOS is a Linux distribution based upon the Nix package manager.  &lt;br /&gt;
&lt;br /&gt;
== Introduction to Nix ==&lt;br /&gt;
NixOS&#039;s fundamental difference is the idea that all software is never installed globally on the system but rather placed in a central content store on your system, also known as the Nix store.  Everything a package needs - the binaries, global default configuration, libraries - are placed together within a directory in the Nix store.  When a package is &#039;installed&#039;, it is simply added to your system&#039;s PATH so that it appears within your environment.&lt;br /&gt;
&lt;br /&gt;
The consequence of this design choice makes a lot of different things possible: &lt;br /&gt;
&lt;br /&gt;
# Multiple versions of the same software can be installed on the same system. It&#039;s even possible to run these different versions at the same time by having different PATHs defined for each environment. &lt;br /&gt;
# Rollbacks are simple. You have the old version of the software installed already. Just change the previous version back as the default. &lt;br /&gt;
# Upgrades are faster. You can leave the current version of some software running while you install and test the new version. Once you&#039;re ready, you can then cut over to the new version. Since everything is already on the system, all the system needs to do is update a few symlinks and you&#039;re upgraded. &lt;br /&gt;
# Entire system upgrades can be rolled back. This idea of having all previous software available on the Nix store means you don&#039;t need to do A/B partitioning. &lt;br /&gt;
&lt;br /&gt;
=== Packages under the hood ===&lt;br /&gt;
Nix packages are also known as &#039;&#039;&#039;derivations&#039;&#039;&#039; and are stored under in the Nix store at {{code|/nix/store/hash-name-version}}. All packages are named with a cryptographic hash that uniquely identifies the package name and version number. All package files are also immutable and should not be changed once it is installed. The Nix package manager will arrange the binaries and libraries in your environment appropriately (by tweaking the PATHs) based on your global system and per-user configuration. &lt;br /&gt;
&lt;br /&gt;
The Nix database is stored at {{code|/nix/var/nix/db}}.&lt;br /&gt;
&lt;br /&gt;
=== Profiles and generations ===&lt;br /&gt;
Profiles define what packages and what version of packages should be available in your environment. Based on your selected profile, Nix will gather all the necessary components spread among different paths into a single unified path. When we upgrade a system, Nix installs all the new packages and creates a new profile referencing the updated packages. In order to facilitate rolling back to a previous version, Nix version controls all profiles into what&#039;s known as a &#039;&#039;&#039;generation&#039;&#039;&#039;. A generation in essence is a specific version of a profile. After a system upgrade, if we ever need to roll back to the system prior to the upgrade, we can reboot into an older generation in the Grub menu.&lt;br /&gt;
&lt;br /&gt;
Profiles are stored under {{code|~/.nix-profile}} which is a symlink to {{code|/nix/var/nix/profiles/default}}. Different generations of the profile are stored {{code|/nix/var/nix/profiles/}}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; handles the profiles and all the symlinks in this location. Paths are also merged by &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Dependencies are called closures ===&lt;br /&gt;
Closures of a derivation is a recursive list of all dependencies that are required.&lt;br /&gt;
&lt;br /&gt;
You can generate a list by running: {{code|nix-store -qR `which man`}} or {{code|nix-store -q --tree `which man`}}&lt;br /&gt;
&lt;br /&gt;
=== Package repositories are called channels ===&lt;br /&gt;
If you ever dealt with Anaconda (the software manager), you will be familiar with the concept of channels. You can think of channels as a package repository. Nix has a few channels which you can see at https://nixos.org/channels:&lt;br /&gt;
* Stable (eg. nixos-20.03): minor bug fixes, no major kernel changes&lt;br /&gt;
* Unstable (eg. nixos-unstable): Main development branch&lt;br /&gt;
* Small (nixos-20.03-small, nixos-unsable-small): Contains fewer binary pakages and faster update cycles. Intended for server environments.&lt;br /&gt;
&lt;br /&gt;
== Cheatsheet ==&lt;br /&gt;
Various commands that were introduced in Chapter 3 of the Nix Pills.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&lt;br /&gt;
! width=&amp;quot;40%&amp;quot; | Command&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{code|nix-env}} &lt;br /&gt;
| Manages environments, profiles, and their generations&lt;br /&gt;
|-&lt;br /&gt;
| {{code|nix-env -i hello}}&lt;br /&gt;
| installs the hello environment&lt;br /&gt;
|-&lt;br /&gt;
| {{code|nix-env --list-generations}}&lt;br /&gt;
| lists all environment generations&lt;br /&gt;
|-&lt;br /&gt;
| {{code|nix-env -q}}&lt;br /&gt;
| lists all derivations&lt;br /&gt;
|-&lt;br /&gt;
| {{code|nix-env -q --references `which hello`}}&lt;br /&gt;
| shows all derivations that are required by the given binary&lt;br /&gt;
|-&lt;br /&gt;
| {{code|nix-env -q --referrers `which hello`}}&lt;br /&gt;
| shows all derivations that are dependent on the given binary&lt;br /&gt;
|-&lt;br /&gt;
| {{code|nix-env --rollback}}&lt;br /&gt;
| rolls back the generation by one&lt;br /&gt;
|-&lt;br /&gt;
| {{code|nix-env -G 3}}&lt;br /&gt;
| sets the environment generation to the given generation (3)&lt;br /&gt;
|-&lt;br /&gt;
| {{code|nix-env -u}} &lt;br /&gt;
| upgrades all packages in the environment&lt;br /&gt;
|-&lt;br /&gt;
| {{code|nix-env -e &#039;*&#039;}}&lt;br /&gt;
| Uninstalls everything from the current environment. You can recover this by running nix-env from the nix store and reinstalling the nix-env derivative or roll back the environment generation.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nix-store -q --tree /run/current-system&amp;lt;/code&amp;gt; &lt;br /&gt;
|List all package dependencies&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nix-store --gc --print-roots&amp;lt;/code&amp;gt;&lt;br /&gt;
|See what is using a dependency&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&lt;br /&gt;
! width=&amp;quot;40%&amp;quot; | Command&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{code|nix-channel --list}} &lt;br /&gt;
| lists all channels. This is configured in ~/.nix-channels&lt;br /&gt;
|-&lt;br /&gt;
| {{code|nix-channel --update}}&lt;br /&gt;
| Synchronizes the channel repo data&lt;br /&gt;
|-&lt;br /&gt;
| {{code|nix-channel --add https://nixos.org/channels/nixos-20.03 nixos}}&lt;br /&gt;
| Adds a channel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To upgrade the system, you can add a new channel and then run {{code|nixos-rebuild switch --upgrade}}. This is equivalent to {{code|nix-channel --update nixos ; nixos-rebuild switch}}.&lt;br /&gt;
&lt;br /&gt;
Remember, users can have their own channels. Only root can update channels that will affect the entire system (and &amp;lt;code&amp;gt;/etc/nixos/configuration.nix&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== Installing NixOS ==&lt;br /&gt;
The installation steps are listed in [https://nixos.org/manual/nixos/stable/index.html#sec-installation section 2.3 of the manual]. I&#039;ll go over the steps to NixOS set up on a non-UEFI system.&lt;br /&gt;
&lt;br /&gt;
Download the NixOS ISO and boot it. Start a terminal and become root using &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;. Format the primary disk with at least one root partition and optionally a swap partition. You may either use &amp;lt;code&amp;gt;fdisk&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;gparted&amp;lt;/code&amp;gt;. Mount the primary root partition as &amp;lt;code&amp;gt;/mnt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Highlight&lt;br /&gt;
| code = # fdisk /dev/sda  # Create a partition for the system, another for swap if desired&lt;br /&gt;
# mkfs.ext4 -L nixos /dev/sda1&lt;br /&gt;
# mount /dev/sda1 /mnt&lt;br /&gt;
| lang = terminal&lt;br /&gt;
}}{{Info&lt;br /&gt;
| title = Change the editor&lt;br /&gt;
| message = If you want to use emacs to edit the initial config, run nix-env -f &#039;&amp;lt;nixpkgs&amp;gt;&#039; -iA emacs first.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Setup NixOS by generating an initial configuration file. Edit the configuration file and ensure that the boot loader is set up. Run &amp;lt;code&amp;gt;nixos-install&amp;lt;/code&amp;gt; to finish the installation.&lt;br /&gt;
&lt;br /&gt;
{{highlight&lt;br /&gt;
| lang = terminal&lt;br /&gt;
| code = # nixos-generate-config --root /mnt &lt;br /&gt;
# cd /mnt   # You can take a look at what&#039;s generated&lt;br /&gt;
&lt;br /&gt;
## Review the configuration file. &lt;br /&gt;
## BIOS systems: ensure that boot.loader.grub.device is set&lt;br /&gt;
## UEFI systems: ensure that boot.loader.systemd-boot.enable is set to true&lt;br /&gt;
# vi /mnt/etc/nixos/configuration.nix&lt;br /&gt;
&lt;br /&gt;
## When you&#039;re ready, set up the system&lt;br /&gt;
# nixos-install&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The {{code|nixos-install}} command will download all the required derivations, set up the boot loader, etc. The last step of the command will prompt for a root password. Once complete, you should be able to reboot into the new installation without the ISO image.&lt;br /&gt;
&lt;br /&gt;
After the system comes up, you should be able to log in as root with the password you provided in the installation step. You can change the system by editing the same {{code|/etc/nixos/configuration.nix}} file as you did originally. For changes to apply, run {{code|nixos-rebuild switch}}.  Any system services that are affected should be automatically restarted by this rebuild process.  If so desired, you can make a separate profile for the rebuild with the {{code|-p profile}} flag so that it shows up as a separate grub option.&lt;br /&gt;
&lt;br /&gt;
You may also use {{code|nixos-rebuild test}} to test the configuration without making it boot by default. You may also use {{code|nixos-rebuild boot}} to do everything as switch did but without switching over until the next reboot.&lt;br /&gt;
&lt;br /&gt;
== Administration tasks ==&lt;br /&gt;
All options that can be set are listed in the NixOS manual.&lt;br /&gt;
* https://nixos.org/nixos/manual/options.html&lt;br /&gt;
&lt;br /&gt;
Section 5 through 42 covers some of the administration tasks:&lt;br /&gt;
* https://nixos.org/nixos/manual/index.html&lt;br /&gt;
&lt;br /&gt;
=== Installing a package in NixOS ===&lt;br /&gt;
For system-wide packages, you can define them in the &amp;lt;code&amp;gt;configuration.nix&amp;lt;/code&amp;gt; configuration file under &amp;lt;code&amp;gt;environment.systemPackages&amp;lt;/code&amp;gt;. Note that all NixOS packages are provided by the &amp;lt;code&amp;gt;pkgs&amp;lt;/code&amp;gt; channel. &lt;br /&gt;
&lt;br /&gt;
{{highlight|lang=text|code=&lt;br /&gt;
environment.systemPackages = with pkgs; [ &lt;br /&gt;
   wget vim &lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
## or&lt;br /&gt;
&lt;br /&gt;
environment.systemPackages = [ pkgs.wget pkgs.vim ];&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
After changing &amp;lt;code&amp;gt;configuration.nix&amp;lt;/code&amp;gt;, rerun {{code|nixos-rebuild switch}} to apply your changes. &lt;br /&gt;
&lt;br /&gt;
==== Installing packages as a user or ad-hoc ====&lt;br /&gt;
You can alternatively install packages using &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; rather than the declarative approach described above. Non-root users can also use nix-env which will update the user&#039;s profile.&lt;br /&gt;
&lt;br /&gt;
Install: {{code|nix-env -iA nixos.wget}}&lt;br /&gt;
&lt;br /&gt;
Uninstall: {{code|nix-env -e wget}}&lt;br /&gt;
&lt;br /&gt;
Remember that any changes to the environment are versioned automatically into a new generation and can be rolled back through grub or with &amp;lt;code&amp;gt;nix-env --rollback&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== System Upgrade ===&lt;br /&gt;
See channels.&lt;br /&gt;
&lt;br /&gt;
Update the channel first&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nix-channel --update nixos&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then upgrade all packages&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nix-env -u &#039;*&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Automatic updates can be enabled by adding to &amp;lt;code&amp;gt;configuration.nix&amp;lt;/code&amp;gt;:&lt;br /&gt;
{{highlight|lang=text|code=&lt;br /&gt;
system.autoUpgrade.enable = true;&lt;br /&gt;
system.autoUpgrade.allowReboot = true;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Garbage collection ===&lt;br /&gt;
See: [https://nixos.org/manual/nix/stable/package-management/garbage-collection.html#:~:text=You%20can%20do%20this%20by%20running%20the%20Nix,wouldn%E2%80%99t%20be%20able%20to%20do%20a%20rollback%20otherwise. https://nixos.org/manual/nix/stable/package-management/garbage-collection.html]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Description&lt;br /&gt;
!Command&lt;br /&gt;
|-&lt;br /&gt;
|To delete all old (non-current) generations of your current profile:&lt;br /&gt;
|&amp;lt;code&amp;gt;nix-env --delete-generations old&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Delete a list of generations&lt;br /&gt;
|&amp;lt;code&amp;gt;nix-env --delete-generations 10 11 14&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Delete generations older than 14 days&lt;br /&gt;
|&amp;lt;code&amp;gt;nix-env --delete-generations 14d&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Clean up nix store (after deleting generations)&lt;br /&gt;
|&amp;lt;code&amp;gt;nix-store --gc&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Delete all old generations of all profiles in &amp;lt;code&amp;gt;/nix/var/nix/profiles&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;nix-collect-garbage -d&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== User Management ===&lt;br /&gt;
By default, entries in /etc/passwd and /etc/group are added ad-hoc by the system. You could use useradd/groupadd to modify the system and have them persist (though, this defeats the point of NixOS).&lt;br /&gt;
&lt;br /&gt;
You can ask NixOS to rewrite the /etc/passwd and /etc/group files as required by the system configuration by setting the &lt;br /&gt;
{{highlight|lang=text|code=&lt;br /&gt;
users.mutableUsers = false&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
To have NixOS create the user for you, define the following in the configuration.nix file:&lt;br /&gt;
{{highlight|lang=text|code=&lt;br /&gt;
users.users.alice = {&lt;br /&gt;
  isNormalUser = true;&lt;br /&gt;
  home = &amp;quot;/home/alice&amp;quot;;&lt;br /&gt;
  description = &amp;quot;Alice Foobar&amp;quot;;&lt;br /&gt;
  extraGroups = [ &amp;quot;wheel&amp;quot; &amp;quot;networkmanager&amp;quot; ];&lt;br /&gt;
  openssh.authorizedKeys.keys = [ &amp;quot;ssh-dss AAAAB3Nza... alice@foobar&amp;quot; ];&lt;br /&gt;
};&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Re-run &amp;lt;code&amp;gt;nixos-rebuild&amp;lt;/code&amp;gt; to apply.&lt;br /&gt;
&lt;br /&gt;
Note: Password is set using {{code|passwd}} and is persistent with the system.&lt;br /&gt;
&lt;br /&gt;
=== Networking ===&lt;br /&gt;
The default configuration uses dhcpd. A static address can be set for a specific interface. &lt;br /&gt;
&lt;br /&gt;
{{highlight|lang=text|code=&lt;br /&gt;
networking.interfaces.eth0.ipv4.addresses = [ {&lt;br /&gt;
  address = &amp;quot;192.168.1.2&amp;quot;;&lt;br /&gt;
  prefixLength = 24;&lt;br /&gt;
} ];&lt;br /&gt;
&lt;br /&gt;
networking.defaultGateway = &amp;quot;192.168.1.1&amp;quot;;&lt;br /&gt;
networking.nameservers = [ &amp;quot;8.8.8.8&amp;quot; ];&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Enable SSH root authentication ===&lt;br /&gt;
{{Highlight&lt;br /&gt;
| code = services.openssh = {&lt;br /&gt;
    enable = true;&lt;br /&gt;
    settings.PermitRootLogin = &amp;quot;yes&amp;quot;;&lt;br /&gt;
    settings.PasswordAuthentication = true;&lt;br /&gt;
  };&lt;br /&gt;
| lang = terminal&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Tasks ==&lt;br /&gt;
&lt;br /&gt;
=== Join FreeIPA domain ===&lt;br /&gt;
FreeIPA is configured using the [https://github.com/NixOS/nixpkgs/blob/3d8a93602bc54ece7a4e689d9aea1a574e2bbc24/nixos/modules/security/ipa.nix security/ipa.nix] module. For my home environment with the FreeIPA server at ipa.home.steamr.com, this is the config that I used:&lt;br /&gt;
{{Highlight&lt;br /&gt;
| code = security.ipa = {&lt;br /&gt;
  enable = true;&lt;br /&gt;
  domain = &amp;quot;home.steamr.com&amp;quot;;&lt;br /&gt;
  realm = &amp;quot;HOME.STEAMR.COM&amp;quot;;&lt;br /&gt;
  server = &amp;quot;ipa.home.steamr.com&amp;quot;;&lt;br /&gt;
  cacheCredentials = true;&lt;br /&gt;
  offlinePasswords = true;&lt;br /&gt;
  basedn = &amp;quot;dc=home,dc=steamr,dc=com&amp;quot;;&lt;br /&gt;
  certificate = pkgs.fetchurl {&lt;br /&gt;
    url = &amp;quot;http://ipa.home.steamr.com/ipa/config/ca.crt&amp;quot;;&lt;br /&gt;
    sha256 = &amp;quot;1svxgn6mq8v1w8jqpn2jx99jwm1zfcpkzslra4mhb365f0fniw6s&amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
system.activationScripts.binbash = lib.stringAfter [ &amp;quot;stdio&amp;quot; ]&lt;br /&gt;
  &#039;&#039;&lt;br /&gt;
    # Create the required /bin/bash symlink;  User profiles use /bin/bash as their shell&lt;br /&gt;
    mkdir -m 0755 -p /bin&lt;br /&gt;
    ln -sfn &amp;quot;${config.system.build.binsh}/bin/bash&amp;quot; /bin/.bash.tmp&lt;br /&gt;
    mv /bin/.bash.tmp /bin/bash # atomically replace /bin/bash&lt;br /&gt;
  &#039;&#039;;&lt;br /&gt;
| lang = text&lt;br /&gt;
}}&lt;br /&gt;
Note the following:&lt;br /&gt;
&lt;br /&gt;
* SHA256 of the server CA certificate was obtained by running: &amp;lt;code&amp;gt;nix-prefetch-url &amp;lt;nowiki&amp;gt;http://$server/ipa/config/ca.crt&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* The activation script creates &amp;lt;code&amp;gt;/bin/bash&amp;lt;/code&amp;gt; as a symlink to bash. This is necessary because users&#039; shell attribute is set to &amp;lt;code&amp;gt;/bin/bash&amp;lt;/code&amp;gt; and the login would fail if it doesn&#039;t resolve to a shell. You might be able to do some sssd overrides, but that&#039;s super annoying to deal with as the entire sssd config is handled by the security/ipa.nix module and I&#039;d rather not have to override what it&#039;s configuring.&lt;br /&gt;
* I ran this on a LXC under Proxmox. The hostname was set to &#039;nx&#039; but the domain for some reason could never be set to &#039;home.steamr.com&#039; despite my best efforts. (&amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt; is correct -- IP resolves to the FQDN then aliases, &amp;lt;code&amp;gt;/etc/resolv.conf&amp;lt;/code&amp;gt; has both domain and search set to home.steamr.com, &amp;lt;code&amp;gt;nsswitch.conf&amp;lt;/code&amp;gt; seems to be correct in using these files.) My guess here is that there&#039;s something not quite right in the LXC environment which is preventing the domain from being set. My work around is to set the hostname to the FQDN (nx.home.steamr.com) and then run &amp;lt;code&amp;gt;ipa-join&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
After rebuilding the system, there will be a message that gets printed with instructions to complete the domain join. SSSD will likely fail until you manually join the domain. See the following output:&lt;br /&gt;
{{Highlight&lt;br /&gt;
| code = [root@nixos:~/nix-configs]# nixos-rebuild switch --flake .#nx&lt;br /&gt;
warning: Git tree &#039;/root/nix-configs&#039; is dirty&lt;br /&gt;
building the system configuration...&lt;br /&gt;
warning: Git tree &#039;/root/nix-configs&#039; is dirty&lt;br /&gt;
stopping the following units: nscd.service&lt;br /&gt;
activating the configuration...&lt;br /&gt;
setting up /etc...&lt;br /&gt;
&lt;br /&gt;
    In order to complete FreeIPA integration, please join the domain by completing the following steps:&lt;br /&gt;
    1. Authenticate as an IPA user authorized to join new hosts, e.g. kinit admin@HOME.STEAMR.COM&lt;br /&gt;
    2. Join the domain and obtain the keytab file: ipa-join&lt;br /&gt;
    3. Install the keytab file: sudo install -m 600 krb5.keytab /etc/&lt;br /&gt;
    4. Restart sssd systemd service: sudo systemctl restart sssd&lt;br /&gt;
| lang = terminal&lt;br /&gt;
}}&lt;br /&gt;
Do what it tells you to do:&lt;br /&gt;
&lt;br /&gt;
# Get a Kerberos ticket for an account with joining capabilities: &amp;lt;code&amp;gt;kinit admin@HOME.STEAMR.COM&amp;lt;/code&amp;gt;&lt;br /&gt;
# with the ticket in place, run &amp;lt;code&amp;gt;ipa-join&amp;lt;/code&amp;gt;&lt;br /&gt;
# You _should_ now be joined to the domain and there should be a keytab file for the machine. Verify with &amp;lt;code&amp;gt;klist -kte /etc/krb5.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
# Restart sssd: &amp;lt;code&amp;gt;systemctl restart sssd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== NFS mounts ====&lt;br /&gt;
If you intend to use NFS after enabling FreeIPA (or if you have a krb5.keytab file), NixOS will try to enable the rpcgss module. If you&#039;re using NixOS in LXC, the module load will always fail since the rpcgss kernel module isn&#039;t where it thinks it is. If you don&#039;t use kerberos for mounting NFS, you can just disable the service by adding: &lt;br /&gt;
{{Highlight&lt;br /&gt;
| code = systemd.services.auth-rpcgss-module.enable = false;&lt;br /&gt;
| lang = text&lt;br /&gt;
}}&lt;br /&gt;
If you do need to use kerberos authentication, you will have to add the NFS service to the host in the FreeIPA interface (Identity -&amp;gt; Services -&amp;gt; Add) and then add the service principal to the kerberos keytab file with something like: &amp;lt;code&amp;gt;ipa-getkeytab -s ipa.home.steamr.com -p nfs/nx.home.steamr.com -k /etc/krb5.keytab&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Override nixpkgs package version ===&lt;br /&gt;
If you need to override specific versions or attributes that are defined by the nixpkgs repo, you can use overlays to override specific things. In the example below, I override the microsoft-edge package to use the most recent version.&lt;br /&gt;
&lt;br /&gt;
Add the following line to your &amp;lt;code&amp;gt;/etc/configuration.nix&amp;lt;/code&amp;gt; file:&lt;br /&gt;
{{Highlight&lt;br /&gt;
| code = nixpkgs.overlays = [ (import /etc/nixos/overlays/overlay.nix) ];&lt;br /&gt;
| lang = text&lt;br /&gt;
}}&lt;br /&gt;
And then create &amp;lt;code&amp;gt;/etc/nixos/overlays/overlay.nix&amp;lt;/code&amp;gt; with the following:&lt;br /&gt;
{{Highlight&lt;br /&gt;
| code = self: super:&lt;br /&gt;
{&lt;br /&gt;
  microsoft-edge = super.microsoft-edge.overrideAttrs (oldAttrs: {&lt;br /&gt;
    src = super.fetchurl {&lt;br /&gt;
      url = &amp;quot;https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable/microsoft-edge-stable_115.0.1901.188-1_amd64.deb&amp;quot;;&lt;br /&gt;
      sha256 = &amp;quot;0xf2d2wxc2hjxz070nkrbgsszylwhck6x655ginjmh0qm76kf4wr&amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
  });&lt;br /&gt;
}&lt;br /&gt;
| lang = terminal&lt;br /&gt;
}}&lt;br /&gt;
If you need to get the appropriate hash, use the nix-prefetch-url command.&lt;br /&gt;
{{Highlight&lt;br /&gt;
| code = $ nix-prefetch-url https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable/microsoft-edge-stable_115.0.1901.188-1_amd64.deb&lt;br /&gt;
path is &#039;/nix/store/kqjnmgrnhgsg56v16rnvv4j4d8fzxlb7-microsoft-edge-stable_115.0.1901.188-1_amd64.deb&#039;&lt;br /&gt;
0xf2d2wxc2hjxz070nkrbgsszylwhck6x655ginjmh0qm76kf4wr&lt;br /&gt;
| lang = terminal&lt;br /&gt;
}}&lt;br /&gt;
If you&#039;d like to update the nixpkgs repo, you&#039;ll have to specify the hash in SRI format (which is just the base64 encoded). That can be accomplished using the nix hash command:&lt;br /&gt;
{{Highlight&lt;br /&gt;
| code = $ nix --extra-experimental-features nix-command  hash to-base64 --type sha256 0xf2d2wxc2hjxz070nkrbgsszylwhck6x655ginjmh0qm76kf4wr&lt;br /&gt;
mRM3zakYwCptfKWYbiaDnPqv9Vt5WnDA7xIK1rlownU=&lt;br /&gt;
| lang = terminal&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Enable IP forwarding ===&lt;br /&gt;
Add the following config:&lt;br /&gt;
{{Highlight&lt;br /&gt;
| code = boot.kernel.sysctl.&amp;quot;net.ipv4.ip_forward&amp;quot; = 1;&lt;br /&gt;
| lang = text&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== nixos-rebuild: line 13: exec: man: not found ===&lt;br /&gt;
You are using nixos-rebuild incorrectly and it&#039;s trying to show you the man page for it. But you don&#039;t have &amp;lt;code&amp;gt;man&amp;lt;/code&amp;gt; installed, so instead you&#039;re getting this error.&lt;br /&gt;
&lt;br /&gt;
The fix is to just figure out what&#039;s wrong with your command. You likely forgot to give it the subcommand (such as &#039;switch&#039;):&lt;br /&gt;
{{Highlight&lt;br /&gt;
| code = [root@nixos:~/nix-configs]# nixos-rebuild --flake .#nx&lt;br /&gt;
/run/current-system/sw/bin/nixos-rebuild: line 13: exec: man: not found&lt;br /&gt;
&lt;br /&gt;
## You probably meant to run nixos-rebuild switch&lt;br /&gt;
[root@nixos:~/nix-configs]# nixos-rebuild switch --flake .#nx&lt;br /&gt;
| lang = terminal&lt;br /&gt;
}}&lt;br /&gt;
{{Navbox Linux}}[[Category:Linux]]&lt;br /&gt;
[[Category:Operating_Systems]]&lt;/div&gt;</summary>
		<author><name>136.159.160.123</name></author>
	</entry>
	<entry>
		<id>https://leo.leung.xyz/wiki/index.php?title=Meraki_MS220-8P&amp;diff=2924</id>
		<title>Meraki MS220-8P</title>
		<link rel="alternate" type="text/html" href="https://leo.leung.xyz/wiki/index.php?title=Meraki_MS220-8P&amp;diff=2924"/>
		<updated>2019-08-22T17:14:38Z</updated>

		<summary type="html">&lt;p&gt;136.159.160.123: /* Rooting the Switch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Meraki MS220-8P is a gigabit PoE switch by Cisco Meraki. Meraki switches are managed through Meraki&#039;s dashboard that resides on their servers and requires a license for the switch to function.&lt;br /&gt;
&lt;br /&gt;
This switch was obtained for free as part of a promotion by Meraki with a 3 year license.&lt;br /&gt;
&lt;br /&gt;
== License ==&lt;br /&gt;
The switch appears to function as a normal switch when it cannot contact the cloud servers. I am unsure if this is the case because my license has not expired yet -- it still routes layer 2 traffic normally even after a factory reset.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
[[File:Ms220-8p-internals.jpg|400px|thumb|right|Meraki MS220-8P Internals]]&lt;br /&gt;
The MS220-8P switch has:&lt;br /&gt;
* Vitesse VCore-III VSC7425 SOC, MIPS 24KEc V5.4&lt;br /&gt;
* 128MB [https://download.siliconexpert.com/pdfs/2016/8/21/1/58/46/713/sam_/manual/2ds_k4t1g08_16_4qj-b_rev1_0-0.pdf K4T1G084QJ-BCE7 DDR2-800 5-5-5 SDRAM chip]&lt;br /&gt;
* 16MB NOR Flash ([https://datasheet.octopart.com/MX25L12845EMI-10G-Macronix-datasheet-12526005.pdf MX25L12845EMI-10G]), containing the loader and initial kernel&lt;br /&gt;
* 128MB NAND Flash ([https://datasheet.octopart.com/MT29F1G08ABADAWP-IT%3AD-Micron-datasheet-11552893.pdf MT29F1G08ABADAWP, 48pin TSOP]), containing the OS kernel+ramdisk and other applications&lt;br /&gt;
&lt;br /&gt;
It also features 2 PSUs, one outputs 12V for the main board, and another 56V 2.6A unit for PoE. The switch will still boot when the PoE power supply is disconnected from mains voltage.&lt;br /&gt;
&lt;br /&gt;
MTD partitions are given to the kernel with the hard coded cmdline in the loader. Partition locations and names:&lt;br /&gt;
{{highlight|lang=terminal|code=&lt;br /&gt;
mtd0: 08000000 00020000 &amp;quot;gen_nand.0&amp;quot;&lt;br /&gt;
mtd1: 00040000 00001000 &amp;quot;loader1&amp;quot;&lt;br /&gt;
mtd2: 003c0000 00001000 &amp;quot;boot1&amp;quot;&lt;br /&gt;
mtd3: 00040000 00001000 &amp;quot;loader2&amp;quot;&lt;br /&gt;
mtd4: 003c0000 00001000 &amp;quot;boot2&amp;quot;&lt;br /&gt;
mtd5: 00080000 00001000 &amp;quot;rsvd&amp;quot;&lt;br /&gt;
mtd6: 00600000 00001000 &amp;quot;bootubi&amp;quot;&lt;br /&gt;
mtd7: 00040000 00001000 &amp;quot;conf&amp;quot;&lt;br /&gt;
mtd8: 00100000 00001000 &amp;quot;stackconf&amp;quot;&lt;br /&gt;
mtd9: 00040000 00001000 &amp;quot;syslog&amp;quot;&lt;br /&gt;
mtd10: 0001f800 0001f800 &amp;quot;board-config&amp;quot;&lt;br /&gt;
mtd11: 00086000 0001f800 &amp;quot;bootroot&amp;quot;&lt;br /&gt;
mtd12: 0140e800 0001f800 &amp;quot;part1&amp;quot;&lt;br /&gt;
mtd13: 0140e800 0001f800 &amp;quot;part2&amp;quot;&lt;br /&gt;
mtd14: 0081f000 0001f800 &amp;quot;storage&amp;quot;&lt;br /&gt;
mtd15: 0020bdb0 0001f800 &amp;quot;SMBStaX-24&amp;quot;&lt;br /&gt;
mtd16: 00292240 0001f800 &amp;quot;SMBStaX-48&amp;quot;&lt;br /&gt;
mtd17: 00230af0 0001f800 &amp;quot;SMBStaX-MS220-8&amp;quot;&lt;br /&gt;
mtd18: 0022be00 0001f800 &amp;quot;SMBStaX-MS220-24&amp;quot;&lt;br /&gt;
mtd19: 0029bc88 0001f800 &amp;quot;SMBStaX-MS220-48&amp;quot;&lt;br /&gt;
mtd20: 0029e7c0 0001f800 &amp;quot;SMBStaX-MS320-24&amp;quot;&lt;br /&gt;
mtd21: 0029ca88 0001f800 &amp;quot;SMBStaX-MS320-48&amp;quot;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[File:MS220-Serial-Jumper4.jpg|150px|thumb|right|UART serial connection available using this pinout.]]&lt;br /&gt;
The serial connection is on jumper 4. The default baud rate is 115200.&lt;br /&gt;
&lt;br /&gt;
== Boot Process Overview ==&lt;br /&gt;
Disclaimer: The information here could be wrong or incomplete.&lt;br /&gt;
&lt;br /&gt;
When power is first applied to the board, the SoC will load the first 256Kb from the NOR flash device into memory and begin execution. This first portion of the NOR flash contains the custom [VCore-III ROM Loader] and its sole purpose is to load the next MTD partition containing the first-stage bootloader into memory, verifying its integrity with a CRC32 check, and passing control to the bootloader. The first-stage bootloader in this case appears to be something like [https://www.linuxboot.org/ LinuxBoot] and contains a custom Linux Kernel and an embedded initramfs. The initramfs contains a custom init program called {{code|bootsh}} that execs {{code|kexec}} against the MTD partition on the NAND flash which contains the Linux Kernel and the embedded initramfs containing  containing the actual Linux Kernel and initramfs used by the operating system. &lt;br /&gt;
&lt;br /&gt;
The Meraki OS that loads appears to be based on OpenWRT. The kernel starts {{code|init}} which is symlinked to different binary called {{code|bootsh}} which executes the startup script in {{code|/etc/init.d/rcS}} as specified by the {{code|sysinit}} line in {{code|/etc/inittab}}. The rest of the system comes up from various startup scripts residing in {{code|/etc/init.d}}.&lt;br /&gt;
&lt;br /&gt;
The stock firmware locks down access by setting the getty to {{code|/usr/bin/serial_logincheck}} which seems to only spawn a shell or accept commands to the {{code|odm}} utility if the device is in manufacturing or RMA mode.  This locked down shell comes up with a {{code|&amp;lt;Meraki&amp;gt;}} prompt and a {{code|WARNING! THIS CONSOLE IS LOGGED! UNAUTHORIZED ACCESS FORBIDDEN!}} message. Despite the threatening {{code|UNRECOGNIZED COMMAND LOGGED TO CLOUD SERVERS.}} message when an invalid command is entered, it does not seem to be logging these commands anywhere.&lt;br /&gt;
&lt;br /&gt;
Continuing on, a few other init scripts will load the kernel modules {{code|vtss_core}}, {{code|vc_click}}, {{code|merakiclick}}, and {{code|elts_meraki}}. Later, other services such as fastcgi (for the built-in control panel), lighttpd, dropbear, config_updater, and the {{code|switch_brain}} are started. The act of loading these kernel modules and starting the {{code|switch_brain}} seems to initialize the underlying SMBStax hardware which brings up the network ports and begins L2 routing. Before this point, the switch ports are inactive. Routing is then controlled through the Click kernel module.&lt;br /&gt;
&lt;br /&gt;
Using Meraki&#039;s stock firmware, a normal startup sequence looks like this.&lt;br /&gt;
{{highlight|lang=terminal|style=max-height: 350px; overflow: auto;|code=&lt;br /&gt;
LinuxLoader built Nov 12 2014 18:01:50&lt;br /&gt;
init_pll ok&lt;br /&gt;
init_spi ok&lt;br /&gt;
init_memctl ok&lt;br /&gt;
wait_memctl ok&lt;br /&gt;
Training DRAM ok&lt;br /&gt;
init_irq ok&lt;br /&gt;
init_dram_uncached ok&lt;br /&gt;
init_icache ok&lt;br /&gt;
init_dcache ok&lt;br /&gt;
enable_caches ok&lt;br /&gt;
init_board ok&lt;br /&gt;
Low level initialization complete, exiting boot mode&lt;br /&gt;
[    0.000000] Linux version 3.18.102-meraki-elemental (ssegal@sf201.meraki.com) (gcc version 5.4.0 (GCC) ) #1 Fri Apr 13 11:18:08 PDT 2018&lt;br /&gt;
[    0.000000] bootconsole [early0] enabled&lt;br /&gt;
[    0.000000] CPU0 revision is: 02019654 (MIPS 24KEc)&lt;br /&gt;
[    0.000000] Determined physical RAM map:&lt;br /&gt;
[    0.000000]  memory: 00317000 @ 00100000 (usable)&lt;br /&gt;
[    0.000000]  memory: 00079000 @ 00417000 (usable after init)&lt;br /&gt;
[    0.000000] User-defined physical RAM map:&lt;br /&gt;
[    0.000000]  memory: 07ff0000 @ 00000000 (usable)&lt;br /&gt;
[    0.000000] Initrd not found or empty - disabling initrd&lt;br /&gt;
[    0.000000] Zone ranges:&lt;br /&gt;
[    0.000000]   Normal   [mem 0x00000000-0x07feffff]&lt;br /&gt;
[    0.000000] Movable zone start for each node&lt;br /&gt;
[    0.000000] Early memory node ranges&lt;br /&gt;
[    0.000000]   node   0: [mem 0x00000000-0x07feffff]&lt;br /&gt;
[    0.000000] Initmem setup node 0 [mem 0x00000000-0x07feffff]&lt;br /&gt;
[    0.000000] Reserving 0MB of memory at 0MB for crashkernel&lt;br /&gt;
[    0.000000] Primary instruction cache 32kB, VIPT, 4-way, linesize 32 bytes.&lt;br /&gt;
[    0.000000] Primary data cache 32kB, 4-way, VIPT, cache aliases, linesize 32 bytes&lt;br /&gt;
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32496&lt;br /&gt;
[    0.000000] Kernel command line:  console=ttyS0,115200 mtdparts=m25p80:0x40000(loader1),0x3c0000(boot1),0x40000(loader2),0x3c0000(boot2),0x80000(rsvd),0x600000(bootubi),0x40000(conf),0x100000(stackconf),0x40000(syslog) ubi.mtd=bootubi ubi.mtd=gen_nand.0 mem=134152192&lt;br /&gt;
[    0.000000] PID hash table entries: 512 (order: -1, 2048 bytes)&lt;br /&gt;
[    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)&lt;br /&gt;
[    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)&lt;br /&gt;
[    0.000000] Writing ErrCtl register=8005040c&lt;br /&gt;
[    0.000000] Readback ErrCtl register=8005040c&lt;br /&gt;
[    0.000000] Cache parity protection enabled&lt;br /&gt;
[    0.000000] Memory: 125064K/131008K available (2655K kernel code, 135K rwdata, 364K rodata, 484K init, 101K bss, 5944K reserved, 0K cma-reserved)&lt;br /&gt;
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1&lt;br /&gt;
[    0.000000] NR_IRQS:66&lt;br /&gt;
[    0.000000] sched_clock: 32 bits at 1kHz, resolution 1000000ns, wraps every 2147483648000000ns&lt;br /&gt;
[    0.001000] Calibrating delay loop... 276.99 BogoMIPS (lpj=138496)&lt;br /&gt;
[    0.012000] pid_max: default: 32768 minimum: 301&lt;br /&gt;
[    0.013000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)&lt;br /&gt;
[    0.014000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)&lt;br /&gt;
[    0.020000] devtmpfs: initialized&lt;br /&gt;
[    0.023000] NET: Registered protocol family 16&lt;br /&gt;
[    0.049000] Switched to clocksource MIPS&lt;br /&gt;
[    0.059000] NET: Registered protocol family 2&lt;br /&gt;
[    0.066000] TCP established hash table entries: 1024 (order: 0, 4096 bytes)&lt;br /&gt;
[    0.073000] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)&lt;br /&gt;
[    0.079000] TCP: Hash tables configured (established 1024 bind 1024)&lt;br /&gt;
[    0.085000] TCP: reno registered&lt;br /&gt;
[    0.089000] UDP hash table entries: 256 (order: 0, 4096 bytes)&lt;br /&gt;
[    0.095000] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)&lt;br /&gt;
[    0.101000] NET: Registered protocol family 1&lt;br /&gt;
[    0.644000] VCORE-III Watchdog Timer enabled (30 seconds).  Prev boot was not caused by WDT reset.&lt;br /&gt;
[    0.654000] futex hash table entries: 256 (order: -1, 3072 bytes)&lt;br /&gt;
[    0.676000] squashfs: version 4.0 (2009/01/31) Phillip Lougher&lt;br /&gt;
[    0.682000] msgmni has been set to 244&lt;br /&gt;
[    0.717000] io scheduler noop registered&lt;br /&gt;
[    0.721000] io scheduler deadline registered (default)&lt;br /&gt;
[    0.727000] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled&lt;br /&gt;
[    0.735000] console [ttyS0] disabled&lt;br /&gt;
[    0.739000] serial8250.0: ttyS0 at MMIO 0x70100000 (irq = 14, base_baud = 13020833) is a 16550A&lt;br /&gt;
[    0.747000] console [ttyS0] enabled&lt;br /&gt;
[    0.747000] console [ttyS0] enabled&lt;br /&gt;
[    0.754000] bootconsole [early0] disabled&lt;br /&gt;
[    0.754000] bootconsole [early0] disabled&lt;br /&gt;
[    0.765000] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xf1&lt;br /&gt;
[    0.772000] nand: Micron MT29F1G08ABADAWP&lt;br /&gt;
[    0.776000] nand: 128MiB, SLC, page size: 2048, OOB size: 64&lt;br /&gt;
[    0.787000] Scanning device for bad blocks&lt;br /&gt;
[    0.904000] m25p80 spi0.1: found mx25l12805d, expected m25p80&lt;br /&gt;
[    0.910000] m25p80 spi0.1: mx25l12805d (16384 Kbytes)&lt;br /&gt;
[    0.915000] 9 cmdlinepart partitions found on MTD device m25p80&lt;br /&gt;
[    0.921000] Creating 9 MTD partitions on &amp;quot;m25p80&amp;quot;:&lt;br /&gt;
[    0.926000] 0x000000000000-0x000000040000 : &amp;quot;loader1&amp;quot;&lt;br /&gt;
[    0.935000] 0x000000040000-0x000000400000 : &amp;quot;boot1&amp;quot;&lt;br /&gt;
[    0.943000] 0x000000400000-0x000000440000 : &amp;quot;loader2&amp;quot;&lt;br /&gt;
[    0.955000] 0x000000440000-0x000000800000 : &amp;quot;boot2&amp;quot;&lt;br /&gt;
[    0.962000] 0x000000800000-0x000000880000 : &amp;quot;rsvd&amp;quot;&lt;br /&gt;
[    0.974000] 0x000000880000-0x000000e80000 : &amp;quot;bootubi&amp;quot;&lt;br /&gt;
[    0.981000] 0x000000e80000-0x000000ec0000 : &amp;quot;conf&amp;quot;&lt;br /&gt;
[    0.992000] 0x000000ec0000-0x000000fc0000 : &amp;quot;stackconf&amp;quot;&lt;br /&gt;
[    1.001000] 0x000000fc0000-0x000001000000 : &amp;quot;syslog&amp;quot;&lt;br /&gt;
[    1.012000] i2c /dev entries driver&lt;br /&gt;
[    1.017000] TCP: cubic registered&lt;br /&gt;
[    1.020000] NET: Registered protocol family 17&lt;br /&gt;
[    1.025000] 8021q: 802.1Q VLAN Support v1.8&lt;br /&gt;
[    1.029000] Meraki MS220-8 board detected&lt;br /&gt;
[    1.034000] i2c-gpio i2c-gpio.1: using pins 6 (SDA) and 5 (SCL)&lt;br /&gt;
[    1.054000] UBI: attaching mtd6 to ubi0&lt;br /&gt;
[    2.061000] UBI: scanning is finished&lt;br /&gt;
[    2.102000] UBI: attached mtd6 (name &amp;quot;bootubi&amp;quot;, size 6 MiB) to ubi0&lt;br /&gt;
[    2.109000] UBI: PEB size: 4096 bytes (4 KiB), LEB size: 3968 bytes&lt;br /&gt;
[    2.115000] UBI: min./max. I/O unit sizes: 1/256, sub-page size 1&lt;br /&gt;
[    2.121000] UBI: VID header offset: 64 (aligned 64), data offset: 128&lt;br /&gt;
[    2.128000] UBI: good PEBs: 1536, bad PEBs: 0, corrupted PEBs: 0&lt;br /&gt;
[    2.134000] UBI: user volume: 0, internal volumes: 1, max. volumes count: 23&lt;br /&gt;
[    2.141000] UBI: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 4249467862&lt;br /&gt;
[    2.150000] UBI: available PEBs: 1532, total reserved PEBs: 4, PEBs reserved for bad PEB handling: 0&lt;br /&gt;
[    2.159000] UBI: background thread &amp;quot;ubi_bgt0d&amp;quot; started, PID 222&lt;br /&gt;
[    2.165000] UBI: attaching mtd0 to ubi1&lt;br /&gt;
[    2.895000] UBI: scanning is finished&lt;br /&gt;
[    2.932000] UBI: attached mtd0 (name &amp;quot;gen_nand.0&amp;quot;, size 128 MiB) to ubi1&lt;br /&gt;
[    2.939000] UBI: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes&lt;br /&gt;
[    2.946000] UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 512&lt;br /&gt;
[    2.952000] UBI: VID header offset: 512 (aligned 512), data offset: 2048&lt;br /&gt;
[    2.959000] UBI: good PEBs: 1024, bad PEBs: 0, corrupted PEBs: 0&lt;br /&gt;
[    2.965000] UBI: user volume: 12, internal volumes: 1, max. volumes count: 128&lt;br /&gt;
[    2.972000] UBI: max/mean erase counter: 1536/683, WL threshold: 4096, image sequence number: 1363641321&lt;br /&gt;
[    2.982000] UBI: available PEBs: 462, total reserved PEBs: 562, PEBs reserved for bad PEB handling: 20&lt;br /&gt;
[    2.991000] UBI: background thread &amp;quot;ubi_bgt1d&amp;quot; started, PID 228&lt;br /&gt;
[    3.062000] devtmpfs: mounted&lt;br /&gt;
[    3.075000] Freeing unused kernel memory: 484K&lt;br /&gt;
[    3.083000] random: init urandom read with 43 bits of entropy available&lt;br /&gt;
[    3.091000] Made it into bootsh: Apr 13 2018 11:17:18&lt;br /&gt;
[    3.096000] bootsh build T-201804131017-Gcbd29c59-ssegal&lt;br /&gt;
[    3.248000] UBIFS: background thread &amp;quot;ubifs_bgt1_4&amp;quot; started, PID 313&lt;br /&gt;
[    3.302000] UBIFS: recovery needed&lt;br /&gt;
[    3.681000] UBIFS: recovery completed&lt;br /&gt;
[    3.685000] UBIFS: mounted UBI device 1, volume 4, name &amp;quot;storage&amp;quot;&lt;br /&gt;
[    3.691000] UBIFS: LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes&lt;br /&gt;
[    3.700000] UBIFS: FS size: 7354368 bytes (7 MiB, 57 LEBs), journal size 1032193 bytes (0 MiB, 6 LEBs)&lt;br /&gt;
[    3.710000] UBIFS: reserved for root: 347364 bytes (339 KiB)&lt;br /&gt;
[    3.715000] UBIFS: media format: w4/r0 (latest is w4/r0), UUID 2EA2ACA1-07FA-472B-BC2D-F0F2DB4314D3, small LPT model&lt;br /&gt;
In manufacturing: FALSE&lt;br /&gt;
In rma mode: FALSE&lt;br /&gt;
[    8.624000] random: nonblocking pool is initialized&lt;br /&gt;
[   12.126000] kexec: Starting new kernel&lt;br /&gt;
[   12.130000] Will call new kernel at 0047a4f0&lt;br /&gt;
[   12.130000] Bye ...&lt;br /&gt;
[    0.000000] Linux version 3.18.57-meraki-elemental (jenkins@dal247.meraki.com) (gcc version 5.4.0 (GCC) ) #2 Fri Aug 24 13:22:04 PDT 2018&lt;br /&gt;
[    0.000000] bootconsole [early0] enabled&lt;br /&gt;
[    0.000000] CPU0 revision is: 02019654 (MIPS 24KEc)&lt;br /&gt;
[    0.000000] Determined physical RAM map:&lt;br /&gt;
[    0.000000]  memory: 0046d000 @ 00100000 (usable)&lt;br /&gt;
[    0.000000]  memory: 00cb3000 @ 0056d000 (usable after init)&lt;br /&gt;
[    0.000000] User-defined physical RAM map:&lt;br /&gt;
[    0.000000]  memory: 07ff0000 @ 00000000 (usable)&lt;br /&gt;
[    0.000000] Initrd not found or empty - disabling initrd&lt;br /&gt;
[    0.000000] Zone ranges:&lt;br /&gt;
[    0.000000]   Normal   [mem 0x00000000-0x07feffff]&lt;br /&gt;
[    0.000000] Movable zone start for each node&lt;br /&gt;
[    0.000000] Early memory node ranges&lt;br /&gt;
[    0.000000]   node   0: [mem 0x00000000-0x07feffff]&lt;br /&gt;
[    0.000000] Initmem setup node 0 [mem 0x00000000-0x07feffff]&lt;br /&gt;
[    0.000000] Reserving 0MB of memory at 0MB for crashkernel&lt;br /&gt;
[    0.000000] Primary instruction cache 32kB, VIPT, 4-way, linesize 32 bytes.&lt;br /&gt;
[    0.000000] Primary data cache 32kB, 4-way, VIPT, cache aliases, linesize 32 bytes&lt;br /&gt;
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32496&lt;br /&gt;
[    0.000000] Kernel command line:  console=ttyS0,115200 mtdparts=m25p80:0x40000(loader1),0x3c0000(boot1),0x40000(loader2),0x3c0000(boot2),0x80000(rsvd),0x600000(bootubi),0x40000(conf),0x100000(stackconf),0x40000(syslog) ubi.mtd=bootubi ubi.mtd=gen_nand.0 mem=0x7FF0000 ramoops.mem_address=0x7FF0000 ramoops.mem_size=0x10000 ramoops.block_size=0x10000&lt;br /&gt;
[    0.000000] PID hash table entries: 512 (order: -1, 2048 bytes)&lt;br /&gt;
[    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)&lt;br /&gt;
[    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)&lt;br /&gt;
[    0.000000] Writing ErrCtl register=8005040c&lt;br /&gt;
[    0.000000] Readback ErrCtl register=8005040c&lt;br /&gt;
[    0.000000] Cache parity protection enabled&lt;br /&gt;
[    0.000000] Memory: 111160K/131008K available (3592K kernel code, 195K rwdata, 736K rodata, 13004K init, 119K bss, 19848K reserved)&lt;br /&gt;
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1&lt;br /&gt;
[    0.000000] NR_IRQS:66&lt;br /&gt;
[    0.000000] sched_clock: 32 bits at 1kHz, resolution 1000000ns, wraps every 2147483648000000ns&lt;br /&gt;
[    0.002000] Calibrating delay loop... 276.99 BogoMIPS (lpj=138496)&lt;br /&gt;
[    0.013000] pid_max: default: 32768 minimum: 301&lt;br /&gt;
[    0.014000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)&lt;br /&gt;
[    0.015000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)&lt;br /&gt;
[    0.018000] ftrace: allocating 12018 entries in 24 pages&lt;br /&gt;
[    0.045000] Performance counters: mips/24K PMU enabled, 2 32-bit counters available to each CPU, irq -1 (share with timer interrupt)&lt;br /&gt;
[    0.052000] devtmpfs: initialized&lt;br /&gt;
[    0.058000] NET: Registered protocol family 16&lt;br /&gt;
[    0.059000] ramoops: using module parameters&lt;br /&gt;
[    0.060000] pstore: Registered ramoops as persistent store backend&lt;br /&gt;
[    0.061000] ramoops: attached 0x10000@0x7ff0000, ecc: 0/0&lt;br /&gt;
[    0.123000] Switched to clocksource MIPS&lt;br /&gt;
[    0.163000] NET: Registered protocol family 2&lt;br /&gt;
[    0.170000] TCP established hash table entries: 1024 (order: 0, 4096 bytes)&lt;br /&gt;
[    0.177000] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)&lt;br /&gt;
[    0.183000] TCP: Hash tables configured (established 1024 bind 1024)&lt;br /&gt;
[    0.190000] TCP: reno registered&lt;br /&gt;
[    0.193000] UDP hash table entries: 256 (order: 0, 4096 bytes)&lt;br /&gt;
[    0.199000] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)&lt;br /&gt;
[    0.206000] NET: Registered protocol family 1&lt;br /&gt;
[    4.456000] VCORE-III Watchdog Timer enabled (30 seconds).  Prev boot was not caused by WDT reset.&lt;br /&gt;
[    4.467000] futex hash table entries: 256 (order: -1, 3072 bytes)&lt;br /&gt;
[    4.499000] squashfs: version 4.0 (2009/01/31) Phillip Lougher&lt;br /&gt;
[    4.505000] msgmni has been set to 217&lt;br /&gt;
[    5.276000] io scheduler noop registered&lt;br /&gt;
[    5.280000] io scheduler deadline registered (default)&lt;br /&gt;
[    5.433000] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled&lt;br /&gt;
[    5.466000] console [ttyS0] disabled&lt;br /&gt;
[    5.470000] serial8250.0: ttyS0 at MMIO 0x70100000 (irq = 14, base_baud = 13020833) is a 16550A&lt;br /&gt;
[    5.479000] console [ttyS0] enabled&lt;br /&gt;
[    5.479000] console [ttyS0] enabled&lt;br /&gt;
[    5.486000] bootconsole [early0] disabled&lt;br /&gt;
[    5.486000] bootconsole [early0] disabled&lt;br /&gt;
[    5.586000] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xf1&lt;br /&gt;
[    5.593000] nand: Micron MT29F1G08ABADAWP&lt;br /&gt;
[    5.597000] nand: 128MiB, SLC, page size: 2048, OOB size: 64&lt;br /&gt;
[    5.609000] Scanning device for bad blocks&lt;br /&gt;
[    6.483000] m25p80 spi0.1: found mx25l12805d, expected m25p80&lt;br /&gt;
[    6.489000] m25p80 spi0.1: mx25l12805d (16384 Kbytes)&lt;br /&gt;
[    6.494000] 9 cmdlinepart partitions found on MTD device m25p80&lt;br /&gt;
[    6.500000] Creating 9 MTD partitions on &amp;quot;m25p80&amp;quot;:&lt;br /&gt;
[    6.505000] 0x000000000000-0x000000040000 : &amp;quot;loader1&amp;quot;&lt;br /&gt;
[    6.665000] 0x000000040000-0x000000400000 : &amp;quot;boot1&amp;quot;&lt;br /&gt;
[    6.675000] 0x000000400000-0x000000440000 : &amp;quot;loader2&amp;quot;&lt;br /&gt;
[    6.722000] 0x000000440000-0x000000800000 : &amp;quot;boot2&amp;quot;&lt;br /&gt;
[    6.740000] 0x000000800000-0x000000880000 : &amp;quot;rsvd&amp;quot;&lt;br /&gt;
[    6.818000] 0x000000880000-0x000000e80000 : &amp;quot;bootubi&amp;quot;&lt;br /&gt;
[    6.942000] 0x000000e80000-0x000000ec0000 : &amp;quot;conf&amp;quot;&lt;br /&gt;
[    6.950000] 0x000000ec0000-0x000000fc0000 : &amp;quot;stackconf&amp;quot;&lt;br /&gt;
[    7.112000] 0x000000fc0000-0x000001000000 : &amp;quot;syslog&amp;quot;&lt;br /&gt;
[    7.143000] tun: Universal TUN/TAP device driver, 1.6&lt;br /&gt;
[    7.148000] tun: (C) 1999-2004 Max Krasnyansky &amp;lt;maxk@qualcomm.com&amp;gt;&lt;br /&gt;
[    7.392000] i2c /dev entries driver&lt;br /&gt;
[    7.398000] TCP: cubic registered&lt;br /&gt;
[    7.402000] Initializing XFRM netlink socket&lt;br /&gt;
[    7.409000] NET: Registered protocol family 10&lt;br /&gt;
[    7.429000] NET: Registered protocol family 17&lt;br /&gt;
[    7.434000] NET: Registered protocol family 15&lt;br /&gt;
[    7.438000] 8021q: 802.1Q VLAN Support v1.8&lt;br /&gt;
[    7.443000] Meraki MS220-8 board detected&lt;br /&gt;
[    7.506000] i2c-gpio i2c-gpio.1: using pins 6 (SDA) and 5 (SCL)&lt;br /&gt;
[    7.614000] UBI: attaching mtd6 to ubi0&lt;br /&gt;
[    8.462000] random: nonblocking pool is initialized&lt;br /&gt;
[    9.373000] UBI: scanning is finished&lt;br /&gt;
[    9.418000] UBI: attached mtd6 (name &amp;quot;bootubi&amp;quot;, size 6 MiB) to ubi0&lt;br /&gt;
[    9.424000] UBI: PEB size: 4096 bytes (4 KiB), LEB size: 3968 bytes&lt;br /&gt;
[    9.431000] UBI: min./max. I/O unit sizes: 1/256, sub-page size 1&lt;br /&gt;
[    9.437000] UBI: VID header offset: 64 (aligned 64), data offset: 128&lt;br /&gt;
[    9.443000] UBI: good PEBs: 1536, bad PEBs: 0, corrupted PEBs: 0&lt;br /&gt;
[    9.450000] UBI: user volume: 0, internal volumes: 1, max. volumes count: 23&lt;br /&gt;
[    9.457000] UBI: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 4249467862&lt;br /&gt;
[    9.466000] UBI: available PEBs: 1532, total reserved PEBs: 4, PEBs reserved for bad PEB handling: 0&lt;br /&gt;
[    9.477000] UBI: background thread &amp;quot;ubi_bgt0d&amp;quot; started, PID 414&lt;br /&gt;
[    9.500000] UBI: attaching mtd0 to ubi1&lt;br /&gt;
[   10.247000] UBI: scanning is finished&lt;br /&gt;
[   10.291000] UBI: attached mtd0 (name &amp;quot;gen_nand.0&amp;quot;, size 128 MiB) to ubi1&lt;br /&gt;
[   10.298000] UBI: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes&lt;br /&gt;
[   10.304000] UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 512&lt;br /&gt;
[   10.311000] UBI: VID header offset: 512 (aligned 512), data offset: 2048&lt;br /&gt;
[   10.318000] UBI: good PEBs: 1024, bad PEBs: 0, corrupted PEBs: 0&lt;br /&gt;
[   10.324000] UBI: user volume: 12, internal volumes: 1, max. volumes count: 128&lt;br /&gt;
[   10.331000] UBI: max/mean erase counter: 1536/683, WL threshold: 4096, image sequence number: 1363641321&lt;br /&gt;
[   10.341000] UBI: available PEBs: 462, total reserved PEBs: 562, PEBs reserved for bad PEB handling: 20&lt;br /&gt;
[   10.350000] UBI: background thread &amp;quot;ubi_bgt1d&amp;quot; started, PID 418&lt;br /&gt;
[   11.514000] devtmpfs: mounted&lt;br /&gt;
[   11.736000] Freeing unused kernel memory: 13004K (8056d000 - 81220000)&lt;br /&gt;
[   12.041000] Made it into bootsh: Aug 24 2018 13:15:33&lt;br /&gt;
[   12.047000] bootsh build switch-10-201808241214-G0a4ba17b-rel-owner&lt;br /&gt;
[   12.203000] UBIFS: background thread &amp;quot;ubifs_bgt1_4&amp;quot; started, PID 564&lt;br /&gt;
[   12.296000] UBIFS: recovery needed&lt;br /&gt;
[   12.599000] UBIFS: recovery completed&lt;br /&gt;
[   12.603000] UBIFS: mounted UBI device 1, volume 4, name &amp;quot;storage&amp;quot;&lt;br /&gt;
[   12.610000] UBIFS: LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes&lt;br /&gt;
[   12.619000] UBIFS: FS size: 7354368 bytes (7 MiB, 57 LEBs), journal size 1032193 bytes (0 MiB, 6 LEBs)&lt;br /&gt;
[   12.628000] UBIFS: reserved for root: 347364 bytes (339 KiB)&lt;br /&gt;
[   12.634000] UBIFS: media format: w4/r0 (latest is w4/r0), UUID 2EA2ACA1-07FA-472B-BC2D-F0F2DB4314D3, small LPT model&lt;br /&gt;
In manufacturing: FALSE&lt;br /&gt;
In rma mode: FALSE&lt;br /&gt;
init started: BusyBox v1.25.1 (2018-08-24 12:51:28 PDT)&lt;br /&gt;
WARNING! THIS CONSOLE IS LOGGED! UNAUTHORIZED ACCESS FORBIDDEN!&lt;br /&gt;
&amp;lt;Meraki&amp;gt; [   13.674000] sysctl: error: &#039;kernel.softlockup_panic&#039; is an unknown key&lt;br /&gt;
[   13.682000] sysctl: error: &#039;kernel.watchdog_thresh&#039; is an unknown key&lt;br /&gt;
[   13.926000] sh: write error: Device or resource busy&lt;br /&gt;
[   14.039000] vtss_core: module license &#039;(c) Vitesse Semiconductor Inc.&#039; taints kernel.&lt;br /&gt;
[   14.047000] Disabling lock debugging due to kernel taint&lt;br /&gt;
[   14.647000] switch: &#039;Meraki MS220-8&#039; board detected&lt;br /&gt;
[   15.621000] sysctl -w vm.panic_on_oom=2&lt;br /&gt;
[   15.648000] vm.panic_on_oom = 2&lt;br /&gt;
[   16.204000] click: starting router thread pid 744 (8081d000)&lt;br /&gt;
[   17.055000] Single synchronous check for reset&lt;br /&gt;
[   17.363000]&lt;br /&gt;
[   17.400000] boot 32 build switch-10-201808241214-G0a4ba17b-rel-owner board elemental mac 0C:8D:DB:CA:CC:AC&lt;br /&gt;
[   17.436000] Module: vtss_core  .text=0xc1411000 .data=0xc14a90b0 .bss=0xc14a9320&lt;br /&gt;
[   17.436000] Module: proclikefs  .text=0xc007c000 .data= .bss=0xc007d040&lt;br /&gt;
[   17.436000] Module: merakiclick  .text=0xc182c000 .data=0xc197c800 .bss=0xc197ca80&lt;br /&gt;
[   17.436000] Module: elts_meraki  .text=0xc1f59000 .data=0xc224faa0 .bss=0xc22513d0&lt;br /&gt;
[   17.436000] Module: vc_click  .text=0xc23ba000 .data=0xc23ebfa0 .bss=0xc23ec130&lt;br /&gt;
[   17.598000] ls -1 /sys/fs/pstore/dmesg-ramoops-* 2&amp;gt;/dev/null&lt;br /&gt;
[   17.630000] /usr/bin/check_bootreason: reading file : No such file or directory&lt;br /&gt;
[   20.435000] !!!!! {/usr/bin/switch_brain} opening /click/switch_port_table/dump_stack_info_and_reset_stack_change failed: No such file or directory&lt;br /&gt;
[   22.515000] chatter: from_sw0 :: FromVitesse: initializing fdma&lt;br /&gt;
[   23.743000] chatter: dhcp_tracker :: DHCPTracker: skipping undersized restore buffer (buf size: 0)&lt;br /&gt;
[   25.112000] !!!!! {/usr/bin/switch_brain} failed writing /click/switch_port_table/set_port_storm_control  errno 2 len 211 data: &amp;quot;PORT 1, ENABLED true\nPORT 2, ENABLED ...&amp;quot;&lt;br /&gt;
[   26.079000] chatter: big_acl :: BigACL: skipping undersized restore buffer (buf size: 0)&lt;br /&gt;
&amp;lt;Meraki&amp;gt; WARNING! THIS CONSOLE IS LOGGED! UNAUTHORIZED ACCESS FORBIDDEN!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Rooting the Switch ==&lt;br /&gt;
I spent a couple weekends figuring out how to get a root shell. The solution I have here isn&#039;t exactly optimal but it works. I couldn&#039;t fit {{code|kexec}} into the stage 1 image which means you will need to manually copy the binary in via the serial port and save it in {{code|/dev/ubi1_4}} which is normally mounted as {{code|/storage}}.&lt;br /&gt;
&lt;br /&gt;
If you are interested in what I actually did to modify the two images below, see [[Rooting the Meraki MS220-8P]] for more information.&lt;br /&gt;
&lt;br /&gt;
{{Warning|Disclaimer: Do at your own risk!|&lt;br /&gt;
Do everything here at your own risk. I assume no liability for any damage done by following this guide.}}&lt;br /&gt;
&lt;br /&gt;
To get a root shell on the console and to enable the root account via SSH, you will need to:&lt;br /&gt;
# Connect the MX25L to a flasher, such as a Raspberry Pi running {{code|flashrom}}&lt;br /&gt;
# Connect J4 to a UART&lt;br /&gt;
# Flash [https://git.steamr.com/leo/meraki-220-8p/blob/master/stage1/dump-patched.dat this modified stage 1 image] using {{code|flashrom}}: {{highlight|lang=terminal|code=&lt;br /&gt;
rpi# flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=600 -c &amp;quot;MX25L12835F/MX25L12845E/MX25L12865E&amp;quot; -w dump-patched.dat&lt;br /&gt;
}}&lt;br /&gt;
# Boot the switch. You should now have a root shell on stage1 with a working version of busybox in the path and {{code|/dev/ubi1_4}} mounted as {{code|/storage}}.&lt;br /&gt;
# Transfer a copy of {{code|kexec}} to {{code|/storage}} (via serial only because there&#039;s no networking, [https://git.steamr.com/leo/meraki-220-8p/tree/master/utils using these ghetto transfer scripts])&lt;br /&gt;
# Copy [https://git.steamr.com/leo/meraki-220-8p/blob/master/stage2/firmware.bin this modified stage 2 image] to {{code|/firmware.bin}}, again via serial&lt;br /&gt;
# Flash the copied image to the NAND flash by running {{highlight|lang=terminal|code=&lt;br /&gt;
# /busybox flash_eraseall /dev/mtd12&lt;br /&gt;
# /busybox nandwrite -p /dev/mtd12 /firmware.bin&lt;br /&gt;
}}&lt;br /&gt;
# Reboot the Switch. If the flash worked properly, the switch should enter stage 2 automatically and a shell should spawn.&lt;br /&gt;
&lt;br /&gt;
{{Info|Default Root Password|&lt;br /&gt;
The default root password using my patched firmware is set to &#039;&#039;&#039;meraki&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Either change it by creating a {{code|/storage/init.sh}} script that modifies the root password or make sure your switch is on a trusted network.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
A custom startup script in {{code|/etc/init.d/S90custom}} will run {{code|/storage/init.sh}} to allow persistent customizations on this switch.&lt;br /&gt;
&lt;br /&gt;
Customization that I found useful and have been using is given below.&lt;br /&gt;
{{highlight|lang=bash|code=&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# Kill everything except for a few critical services&lt;br /&gt;
# We do not want Meraki&#039;s software talking to the cloud.&lt;br /&gt;
ps | grep -vE &#039;\[|init|dropbear|syslog|ntpd|watchdog&#039; | awk &#039;{print $1}&#039; | while read i ; do kill -9 $i ; done&lt;br /&gt;
freeze -w&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
# Adjust the LED to green&lt;br /&gt;
echo 1 &amp;gt; /click/sw0_ctrl/power_led_green&lt;br /&gt;
echo 0 &amp;gt; /click/sw0_ctrl/power_led_orange&lt;br /&gt;
&lt;br /&gt;
# Start web services and allow port 80 in for the web control panel. The credentials set are:&lt;br /&gt;
#   Username: admin&lt;br /&gt;
#   Password: password&lt;br /&gt;
echo &amp;quot;admin:Meraki Manual Configuration. The default login is the serial number with no password.:cfd8fe3073e8e63a9cfeb715c51b589c&amp;quot; &amp;gt;&amp;gt; /tmp/lighttpd-htdigest.user&lt;br /&gt;
/usr/bin/fastcgi -s /tmp/fcgi_sock &amp;amp;&lt;br /&gt;
lighttpd -f /etc/lighttpd.conf &amp;amp;&lt;br /&gt;
&lt;br /&gt;
# Adjust firewall via click&lt;br /&gt;
echo &amp;quot;allow tcp dst port 22, allow tcp dst port 80&amp;quot; &amp;gt; /click/nat/from_sw0_filter/config&lt;br /&gt;
&lt;br /&gt;
# Cleanup&lt;br /&gt;
killall sync_log&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Now What ===&lt;br /&gt;
The switch is a Click Modular Router with the addition of a couple proprietary packages to interface with the SMBStax system. Meraki&#039;s custom binaries interface with Click programatically and the only way to change configs with Click is through the {{code|/click}} virtual filesystem.&lt;br /&gt;
&lt;br /&gt;
A control panel can be accessed if you port forward port 80 via SSH or by modifying the existing click rule with&lt;br /&gt;
{{highlight|lang=terminal|code=&lt;br /&gt;
## Add this to /storage/init.sh to have the control panel accessible externally&lt;br /&gt;
# echo &amp;quot;allow tcp dst port 22, allow tcp dst port 80&amp;quot; &amp;gt; /click/nat/from_sw0_filter/config&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Things to do:&lt;br /&gt;
* Figure out how to manage the switch via Click&lt;br /&gt;
&lt;br /&gt;
== Dumping Flash Data ==&lt;br /&gt;
=== NOR Flash ===&lt;br /&gt;
The 16-Pin SOP for the MX25L12845E chip is as follows:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
# NC/SIO3&lt;br /&gt;
# VCC&lt;br /&gt;
# NC&lt;br /&gt;
# PO2 - parallel data out/in, can be NC in serial mode&lt;br /&gt;
# PO1&lt;br /&gt;
# PO0&lt;br /&gt;
# CS# - chip select&lt;br /&gt;
# SO/SIO1/PO7 - Serial data output for 1x IO&lt;br /&gt;
|&lt;br /&gt;
16. SCLK - clock input&amp;lt;br /&amp;gt;&lt;br /&gt;
15. SI/SIO0 - Serial data input for 1x IO&amp;lt;br /&amp;gt;&lt;br /&gt;
14. PO6&amp;lt;br /&amp;gt;&lt;br /&gt;
13. PO5&amp;lt;br /&amp;gt;&lt;br /&gt;
12. PO4&amp;lt;br /&amp;gt;&lt;br /&gt;
11. PO3 &amp;lt;br /&amp;gt;&lt;br /&gt;
10. GND&amp;lt;br /&amp;gt;&lt;br /&gt;
9. WP#/SIO2 - Write protection, connect to GND&lt;br /&gt;
|}&lt;br /&gt;
[[File:Mx25l Pinout.jpg|350px|thumb|right|MX25L Pinout]]&lt;br /&gt;
&lt;br /&gt;
==== Raspberry Pi + Flashrom ====&lt;br /&gt;
To read the chip using a Raspberry Pi and flashrom, we can use 1x serial IO by connecting the pins according to this table:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;float: left; width: auto; margin-right: 10px;&amp;quot;&lt;br /&gt;
! RPi header !! SPI flash !! MX25L Pin&lt;br /&gt;
|-&lt;br /&gt;
| 25 || GND || 10&lt;br /&gt;
|-&lt;br /&gt;
| 24 || /CS || 7&lt;br /&gt;
|-&lt;br /&gt;
| 23 || SCK || 16&lt;br /&gt;
|-&lt;br /&gt;
| 21 || DO  || 8&lt;br /&gt;
|-&lt;br /&gt;
| 19 || DI  || 15&lt;br /&gt;
|-&lt;br /&gt;
| 17 || VCC 3.3v || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WriteProtect (WP#, pin 9) should be connected to GND according to the datasheet. Leaving it floating still seems to work.&lt;br /&gt;
&lt;br /&gt;
Refer to the Raspberry Pi pinout at https://i.stack.imgur.com/eLPtx.png.&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi should have SPI enabled by adding this line to {{code|/boot/config.txt}}:&lt;br /&gt;
{{highlight|lang=text|code=&lt;br /&gt;
device_tree_param=spi=on&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The {{code|/dev/spidev0.0}} device should exist and flashrom should be able to detect the flash chip.&lt;br /&gt;
{{highlight|lang=terminal|code=&lt;br /&gt;
[root@alarmpi alarm]# flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=1000&lt;br /&gt;
flashrom v1.0 on Linux 4.14.92-1-ARCH (armv7l)&lt;br /&gt;
flashrom is free software, get the source code at https://flashrom.org&lt;br /&gt;
&lt;br /&gt;
Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).&lt;br /&gt;
Found Macronix flash chip &amp;quot;MX25L12805D&amp;quot; (16384 kB, SPI) on linux_spi.&lt;br /&gt;
Found Macronix flash chip &amp;quot;MX25L12835F/MX25L12845E/MX25L12865E&amp;quot; (16384 kB, SPI) on linux_spi.&lt;br /&gt;
Multiple flash chip definitions match the detected chip(s): &amp;quot;MX25L12805D&amp;quot;, &amp;quot;MX25L12835F/MX25L12845E/MX25L12865E&amp;quot;&lt;br /&gt;
Please specify which chip definition to use with the -c &amp;lt;chipname&amp;gt; option.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Dump the data using {{code|-r filename}}.&lt;br /&gt;
{{highlight|lang=terminal|code=&lt;br /&gt;
[root@alarmpi alarm]# flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=300 -c &amp;quot;MX25L12835F/MX25L12845E/MX25L12865E&amp;quot; -r dump7.dat&lt;br /&gt;
flashrom v1.0 on Linux 4.14.92-1-ARCH (armv7l)&lt;br /&gt;
flashrom is free software, get the source code at https://flashrom.org&lt;br /&gt;
&lt;br /&gt;
Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).&lt;br /&gt;
Found Macronix flash chip &amp;quot;MX25L12835F/MX25L12845E/MX25L12865E&amp;quot; (16384 kB, SPI) on linux_spi.&lt;br /&gt;
Reading flash... done.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Flash Contents ====&lt;br /&gt;
The dumped 16MB NOR flash contents has the same partition layout shown previously. Each partition can be extracted out using {{code|dd}} with these boundaries:&lt;br /&gt;
{{highlight|lang=terminal|code=&lt;br /&gt;
# loader1          262144      256        0.25MB&lt;br /&gt;
# boot1            3932160     3840       3MB&lt;br /&gt;
# loader2          262144      256        0.25MB&lt;br /&gt;
# boot2            3932160     3840       3MB&lt;br /&gt;
# rsvd             524288      512        0.5MB&lt;br /&gt;
# bootubi          6291456     6144       6MB&lt;br /&gt;
# conf             262144      256        0.25MB&lt;br /&gt;
# stackconf        1048576     1024       1MB&lt;br /&gt;
# syslog           262144      256        0.25MB&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Split the files out using {{code|dd}}:&lt;br /&gt;
{{highlight|lang=terminal|code=&lt;br /&gt;
$ dd if=dump.dat of=loader1    bs=1 skip=$((0x0))      count=262144&lt;br /&gt;
$ dd if=dump.dat of=boot1      bs=1 skip=$((0x40000))  count=3932160&lt;br /&gt;
$ dd if=dump.dat of=loader2    bs=1 skip=$((0x400000)) count=262144&lt;br /&gt;
$ dd if=dump.dat of=boot2      bs=1 skip=$((0x440000)) count=3932160&lt;br /&gt;
$ dd if=dump.dat of=rsvd       bs=1 skip=$((0x800000)) count=524288&lt;br /&gt;
$ dd if=dump.dat of=bootubi    bs=1 skip=$((0x880000)) count=6291456&lt;br /&gt;
$ dd if=dump.dat of=conf       bs=1 skip=$((0xe80000)) count=262144&lt;br /&gt;
$ dd if=dump.dat of=stackconf  bs=1 skip=$((0xec0000)) count=1048576&lt;br /&gt;
$ dd if=dump.dat of=syslog     bs=1 skip=$((0xfc0000)) count=262144&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Each partition in brief detail:&lt;br /&gt;
{|&lt;br /&gt;
! Partition&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| loader1, loader2 || Contains the VCore-III ROM Loader that initializes the board and loads the first-stage bootloader. Both MTD partition data are identical.&lt;br /&gt;
|-&lt;br /&gt;
| boot1, boot2 || Contains the linux kernel and embedded initramfs for the first-stage bootloader. Both MTD partition data are identical.&lt;br /&gt;
|-&lt;br /&gt;
| bootubi  || Contains a UBI volume. Not sure what it contains yet&lt;br /&gt;
|-&lt;br /&gt;
| conf  || Contains just these values: {{highlight|lang=text|code=&lt;br /&gt;
#@(#)VtssConfig&lt;br /&gt;
MAC=00:18:0a:02:03:04&lt;br /&gt;
BOARDID=123456&lt;br /&gt;
}}&lt;br /&gt;
|-&lt;br /&gt;
| rsvd, stackconf, and syslog || These MTD partitions are completely erased (all FF&#039;s)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The loader will attempt to load their respective boot partitions and start the kernel. If the kernel fails to load properly for any reason, it will jump execution to the next loader. This fallback mechanism seems to make the device robust against failed firmware updates that&#039;s sent over the cloud by Meraki.&lt;br /&gt;
&lt;br /&gt;
The first-stage bootloader initramfs contains a few empty directories as well as two static binaries {{code|bootsh}} and {{code|kexec}}. The {{code|bootsh}} binary will {{code|kexec}} the second-stage Linux Kernel from the 128MB flash. Decompiling the binary suggests that {{code|bootsh}} can boot into a shell if a &#039;magic key&#039; is pressed while the device is in &#039;manufacturing&#039; or &#039;RMA&#039;. Since the switch isn&#039;t in this state, {{code|bootsh}} will just {{code|kexec}} to the next kernel regardless of what you do on the serial console.&lt;br /&gt;
&lt;br /&gt;
=== NAND Flash ===&lt;br /&gt;
After gaining root access to the first stage kernel, use {{code|nanddump}} to dump the flash contents into a file. {{code|nanddump}} isn&#039;t included in the stock firmware, so you will need to flash it into the stage 1 initramfs image.&lt;br /&gt;
&lt;br /&gt;
To dump MTD 12:&lt;br /&gt;
{{highlight|lang=terminal|code=&lt;br /&gt;
# nanddump -f mtd12 /dev/mtd12&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
You may also do this when the Meraki OS loads as well provided that you have gained root access.&lt;br /&gt;
&lt;br /&gt;
== The {{code|/click}} Filesystem ==&lt;br /&gt;
The Meraki switch uses Click with two additional proprietary packages. The project source is at https://github.com/kohler/click.&lt;br /&gt;
&lt;br /&gt;
There is however no {{code|click-install}} on the OS as it seems like any custom changes that are made by Meraki is done through their own binaries. The only way to manipulate the switch is to mess with Click through the virtual filesystem.&lt;br /&gt;
&lt;br /&gt;
Things of note are:&lt;br /&gt;
* The power LED can be controlled through {{code|/click/sw0_ctrl/power_led_{green,orange}}}&lt;br /&gt;
* Other switch port values can be viewed through  {{code|/click/sw0_ctrl/}}&lt;br /&gt;
&lt;br /&gt;
There are {{code|click_read}}, {{code|click_write}}, {{code|click_eventd}} binaries in the stock firmware.&lt;br /&gt;
&lt;br /&gt;
Meraki uses the default {{code|/etc/switch.template}} to populate the initial Click configuration. Additional configs seem to be loaded by the {{code|switch_brain}} from {{code|/storage/config.local}}. &lt;br /&gt;
&lt;br /&gt;
My {{code|/storage/config.local}} looks something like this:&lt;br /&gt;
{{highlight|lang=text|code=&lt;br /&gt;
xport[0c:8d:db:xx:xx:xx]8:force_speed 1Gfdx&lt;br /&gt;
xport[0c:8d:db:xx:xx:xx]4:enabled true&lt;br /&gt;
xport[0c:8d:db:xx:xx:xx]4:allow_untagged_in true&lt;br /&gt;
xport[0c:8d:db:xx:xx:xx]4:pvid 1&lt;br /&gt;
xport[0c:8d:db:xx:xx:xx]4:untagged_vid 1&lt;br /&gt;
xport[0c:8d:db:xx:xx:xx]2:allow_untagged_in true&lt;br /&gt;
xport[0c:8d:db:xx:xx:xx]2:pvid 1&lt;br /&gt;
xport[0c:8d:db:xx:xx:xx]2:untagged_vid 1&lt;br /&gt;
xport[0c:8d:db:xx:xx:xx]1:force_speed 100fdx&lt;br /&gt;
static_wired_ip_enabled true&lt;br /&gt;
static_wired_ip 10.x.x.x&lt;br /&gt;
static_wired_netmask 255.255.252.0&lt;br /&gt;
static_wired_gateway 10.x.x.x&lt;br /&gt;
static_wired_dns1 10.x.x.x&lt;br /&gt;
static_wired_ip6_enabled false&lt;br /&gt;
static_wired_ip6_plen 64&lt;br /&gt;
static_wired_vid 1&lt;br /&gt;
mtunnel_http_proxy_enabled false&lt;br /&gt;
mtunnel_http_proxy_userpwd_enabled false&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Some settings, such as the firewall, are set by {{code|switch_brain}} again regardless of the {{code|switch.template}} file.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
Meraki&#039;s open source code can be found at:&lt;br /&gt;
* https://dl.meraki.net/switch-8-10-20170825.tar.bz2&lt;br /&gt;
* http://dl.meraki.net/linux/index.html&lt;br /&gt;
&lt;br /&gt;
=== OpenWRT ===&lt;br /&gt;
* https://openwrt.org/docs/guide-developer/crosscompile&lt;/div&gt;</summary>
		<author><name>136.159.160.123</name></author>
	</entry>
</feed>