Skip to content

Instantly share code, notes, and snippets.

@espoelstra
Last active October 20, 2023 17:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save espoelstra/5151853222f116453fa845a0f3beffda to your computer and use it in GitHub Desktop.
Save espoelstra/5151853222f116453fa845a0f3beffda to your computer and use it in GitHub Desktop.
Nikau on Chromebooks for fun and profit

Newer Chromebooks block sudo in crosh, so you need to Ctrl+Alt+F2 (or higher) to get to a vty where you can login as root directly. Then you should run chromeos-setdevpasswd so that you can login as chronos in the VTY and use sudo with its password to perform any necessary elevations. It still won't allow sudo in the crosh shell in a GUI session (while older ChromeOS releases do), but the vast majority of scripts like Chromebrew/et al that use sudo expect you to NOT run directly as root, so enabling sudo this way is the best option and allows you to still use some of those tools via the VTY.

#Ctrl+Alt+F2
root
chromeos-setdevpasswd
#'yourpassword'
#'yourpassword'#again
exit #or Ctrl+d

Logout of the root session and switch back to the GUI and then logout/exit any chronos session in Crosh and start a new one by typing shell in Crosh.

crosh> shell
Password: #'yourpassword' # this prompt may only be on older devices, newer ones block the sudo call crew tries to make loading its session

Now you need to install Chromebrew, follow the directions from the README.md not their docs site, which is slightly out of date.

exec bash --init-file <(curl -Ls git.io/vddgY)

Once it is installed you must source the ~/.bashrc to get the Chromebrew variables into your environment.

yes | crew install rust ld_default
# the latter pulls in buildessential and gcc and other stuff we'd need anyways to actually build anything within rust/cargo

On multiple x86_64 systems I've had to downgrade to rust 1.72.1 instead of rust 1.73 to work around an llvm issue, but on armv7 systems I haven't had that issue.

rustup default 1.72

You can just run these exports if the only rust/cargo thing you want is nikau. Otherwise you may want to add these variables to your $HOME/.bashrc and save it then run . ~/.bashrc because rust-y things will fail due to permissions issues on ChromeOS (noexec mounts for $HOME and /tmp and other things like that), while using /usr/local allows everything necessary to build/use the software.

export RUSTUP_HOME=/usr/local/share/rustup
export CARGO_INSTALL_ROOT=/usr/local    
export TMPDIR=/usr/local/tmp
#TMPDIR gets used by the tempdir crate, and intermediate compiles need to be in a partition/path not marked noexec

Once you have those set you can install nikau.

cargo install nikau

You can run nikau or nikau --help to see the options.

You can run the server as the chronos user in a Crosh shell because it has access to all the existing input devices to forward so it doesn't require sudo/root (but you'll have to restart the nikau process if you add a new input device to the system later).

This is great because it means (on newer ChromeOS releases where sudo in Crosh is blocked) you don't need to leave a vty open to sudo and start the process and you can view the logs more easily.

If you don't mind accessing the vty to view the logs, you could run it with sudo -E there and then nikau can automatically handle newly plugged devices as well.

In order to actually connect clients to the server you are running, you DO need to do 1 more thing with sudo, you need to add an iptables rule to allow communication on 1213. You will need to do this every time ChromeOS boots, as the iptables-save

sudo iptables -L -v -n --line-numbers #show current rules

sudo iptables -A INPUT -p udp --dport 1213 -j ACCEPT -w
# this applies immediately, so you should be able to run the server in a Crosh shell in the GUI

You'll need to run the client with sudo -E /path/to/nikau [server|client] to access and create new input devices (requires root or being in the right group, and groups can't be changed on ChromeOS without setting the rootfs to rw which breaks other things), and since with sudo it executes as the root user but /root/ is in the read-only mount for /, with sudo -E it puts the .config and stuff in the chronos user's home directory instead of trying to write it in /root/.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment