-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Container can't mount host's /mnt/boot #2371
Comments
Decided I won't try this, as it has way too much possibility of volume corruption: devices:
- "/dev/sda1:/dev/sda1" I can make a second container that has |
or maybe I just give my container |
@shaunco , |
Thanks @cywang117! The script works, for now, but I'd really prefer something like the PR I submitted ( #2372 ). I'm aware of the dangers, but it is unrealistic to have customers ship devices back to us or for us to configure and send brand new images they can write to a thumbdrive with Etcher for a full reflash when they need minor network changes (static<->dynamic, DNS changes, an 802.1x cert needing updated, new SSL MITM proxy, disabling 8.8.8.8, redsocks config, wifi settings, etc). With this SSH accessible configuration app, we've given them the ability to reconfigure specific parameters as long as they can get a laptop on the same network. Next up is figuring out how to expose it over |
Hey @shaunco ! Thanks for taking the time to submit a PR. Unfortunately we have a strict process for evaluating the addition of interfaces to the Supervisor, as Supervisors have to be backwards-compatible with both old and new OS versions. What this means is that each feature added also becomes part of the support burden for future OS versions. You listed quite a few pieces of functionality. Redsocks config for example can be handled through the Supervisor API so doesn't require the boot mount, but for ther others, I see why you'd want to access to the boot mount for them, as we don't have runtime configuration options for them. For the NetworkManager configs though, they can be managed from within the container with DBus, which we support as a label. Perhaps if you have a support account, you can raise individual features you'd be interested in that we don't support? |
Seems like a strange position to instruct balena users to modify all these files in the boot partition prior to provisioning/flashing a device, but then give limited to no ability to edit them via console/ssh/API/container. Either we are the admins of the device and should be able to configure these files at will or we are not. If allowing a bind mount of We requested these features through our paid support and our customer success lead over a year ago (8/24/2023), along with the request for ANY form of local configuration (SSH, console, etc) that didn't require reflashing the box. The response we got was:
... so, that is pretty much what we've done. It just turns out we can't actually edit most of the persistent config that we see break customer installs over and over and over again, so I opened an issue and submitted a 1 line PR that fixes the issue. As for configuration via Supervisor API / DBus... RedsocksSupervisor API exposes an extremely limited set of redsocks config capabilities, any just finally added Network ManagerThe DBus API for NetMgr writes to
config.jsonSupervisor API has the best support here, but we often attach bash scripts to udev rules:
which can't be done through the Supervisor API. We use this method to populate |
Hi @shaunco, thanks again for your feedback and the PR We understand your frustration in the inability to get access to files in the boot partition for some configurations. While we strive to continuously improve our product with features that provide value to users, we also are very mindful about the balance between utility, compatibility across device types and OS versions and risk. Writing to the boot partition is risky, it is a FAT filesystem, which is not journaled, meaning changes to files in that partition, if they are interrupted by a power cut, could lead to corruption and potentially bricking devices. Because of this, we have invested good effort in creating mechanisms to write safely to that partition (see our [fatrw project](https://github.com/balena-os/fatrw)), but even with that, we sometimes still see issues with corruption. This is the reason we have chosen not to provide services with an easy way to bind mount to It is in our plans to provide some config variables to modify some of the settings that require modifications to files in the boot partition, but we cannot unfortunately provide and ETA on any of those features as they have yet to be prioritized. However, in general, configurations in the boot partition are meant to be somewhat static (related to the risk of dynamically changing files in that partition), and there are good alternatives for dynamically changing most of the configurations you mention via containers. Redsocks While we are aware there are multiple settings we don't surface in the host-config feature of the supervisor, this is because this interface is meant as a generic, implementation independent mechanism of configuring OS proxy settings. Designing it this way would allow us to change the proxy service if we find a better alternative, without impacting user applications. For users that need more flexibility in their configuration, there is also the option of running a proxy service within a container and using [network_mode: service](https://docs.docker.com/reference/compose-file/services/#network_mode), for other containers to ensure they communicate via the proxy. Some of our customers chose this option for proxying connections or making devices available on a VPN. Network Manager As you pointed out, static configurations will overwrite dynamic configurations, but this will only happen if the static versions are available, and only until the service container can start and re-configure the network. UDEV rules Regarding your specific use case for DNS configuration, it might be worth opening up a support ticket for that. The OS includes its own DNS server and will default to communicating with Hope this helps, again, we appreciate your feedback, and please do reach us on support if there are any use cases you think cannot be covered via these interfaces. |
Feel free to refer back to the tickets I opened in 2022 and 2023 that have detailed explanations of the use cases. Happy to forward them again if you want to email me. For DNS, it is not a matter of using 8.8.8.8 - that is blocked on 100% of the customer deployments we go into (as is any public DNS service). No enterprise in their right mind would ever allow access to public DNS. The two setups we see are either a local DNS server configured via DHCP/static network config or quite literally NO DNS. That is, there is no local DNS server and all port 53 TCP/UDP communications are blocked. There is NO DNS server, so our only option is to configure the balenaOS hosts file to have the entries needed for balena-cloud (or open-balena) and other services we access. On the Network Manager case, static IP settings are quite prevalent in OT environments - we rarely find DHCP servers. So, we statically configure entries in the boot partition's The same issues apply when the customer needs to change proxy settings, MITM certs, and a few other things... Obviously, we found a way to do this using the
|
The DNS setting can also be pre-configured via So, my understanding of your requirement is that you need a way to set some factory network settings, but be able to override them dynamically if the need arises. Is that correct? This is good insight and I agree we are still lacking some features in that area, we don't yet have a way to preload environment variables, and there are several settings that cannot be modified dynamically via D-Bus, config variable, or the supervisor API (MITM certificate is a good example of that). While it's unlikely that we'll provide unlimited access to the boot partition, outlining the problem this way provides a good path forward for prioritizing the implementation of these missing features. For now, using something like the mount-partitions script is your best way forward for accessing the boot partition. Note that this script is very complex as it needs to deal with multiple types of boot partitions, on different device types, including systems with secure boot. If your fleet is generally uniform, you might be able to simplify to something like
For modifying files within that partition programmatically, we we would also recommend taking a look at https://github.com/balena-os/fatrw |
This isn't just about dynamic modification... I feel like I must be doing a horrible job of explaining this, so I'll try again. Our balenaOS based devices are deployed to environments that are not under our control. Sometimes those environments use DHCP, but most of the time they do not. Sometimes they have DNS servers, but often they do not. They almost always (95%+) block all external DNS. Sometimes they have proxies, sometimes they have MITM proxies. No matter what they have on the day we deploy our box, the environment might change 3 months later or 6 months later or even 5 years later because some IT or infosec person or a networking consultant convinced that enterprise they need to redo EVERYTHING. The real world is never truly static. When these changes happen, the IT teams running these environments where our balenaOS appliance is deployed need to be able to log in to something and make changes to the network settings on it. They're happy to do the work if there is a way, but if there is not a way, they are just going to unplug our device and make it our problem... and that means we either need to fly someone across the globe to go reflash the box (losing container volumes) or send seemingly insane directions to some IT person at the place where the box is deployed telling them to use a USB thumbdrive and Etcher to download a hand-crafted image for their env (because it contains a new config.json and system-connections files) and then to go plug it into our device, wait for the power to go out, and then remove it and power the device back on (also losing container volumes). InfoSec on the customer side rightly loses their minds over this, because it is nuts, and then we spend 3 months going back and forth with the customer about "Why isn't there a web portal or ssh server I can log into to change these settings??? Every other appliance on my network has that!" and then eventually they get angry and kick us off their network and we lose a customer. What we need is a web portal, TTY console, or SSH server built into Balena that allows a local network administrator to reconfigure ALL network settings, but the balena support team told me that would Thank you for the minimized script!
I'm still unclear on this. We have unlimited access while constructing the image and flashing it. We have unlimited access via in the balena-cloud shell... but we don't get programmatic unlimited access because we "might knock the box offline". But here's the thing - in the case I described above, the box is ALREADY offline. That programmatic access is used to save us an 18 hour flight to go manually fix it... and if it doesn't work, ok, then we're back to the 18 hour flight option. Also, it seems much more likely that we'd manually break something via balena-cloud shell than we would programmatically through tested code and a UI that controls what can be changed. |
Thanks for the additional information, your clarification aligns with my understanding so It's probably me that is not communicating properly. To specify my understanding
Currently our product allows you to set factory settings (1), in config.json, system-connections, etc. It also allows you to programmatically change some (not all, I'm aware) of these settings via containers (2). The problem is that these configuration mechanisms are not very compatible. Factory settings always take precedence so the device will temporarily revert to the factory configuration until the container can run. If the engine has an issue, the device gets locked from the network. So the way I understand it, is that we are missing some unified OS configuration interface that meets the two requirements listed above and persists changes across reboots. This is compatible with what you say here
However, the fact that balenaOS currently uses NetworkManager, redsocks, etc., doesn't mean that will always be the case, so the interface needs to be implementation independent so Balena users can safely update the OS without breaking their apps. This also relates to providing access to the boot partition, while it is technically possible as you have seen, it's not a path we would recommend for everyone as it reduces independence between the app and the OS, and could potentially make OS updates harder which has other implications. Let me know if you agree with my assessment above. I'll start pushing for some internal discussions on how this interface could be defined, but it might take some time. |
Correct on 1 and 2, and that unified os-config interface would be ideal, although I get this is unlikely anytime soon. I also understand that balenaOS can move away from NetworkManager, redsocks, etc any time - but for our devices, we are in control of when balenaOS updates and in control of when our config container updates, so making the configuration partition easily accessible ( |
Our balena devices are deployed in customer environments, and often the customer needs to reconfigure network settings, proxies, udev entries (and associated sh scripts), and other stuff that is in the boot partition. Given that this is all on internal flash memory, it is nearly impossible for the customer to do. This means configuring a new image, sending it to the customer to use balena Etcher, and having them reflash the box - an all around terrible experience. When I first brought this up, the Balena team pointed me at https://github.com/balena-os/wifi-connect , but it is incredibly limited in its abilities. We looked at the Supervisor API, but it can't configure Network Manager settings and can't put shell scripts into the boot partition for udev rules to run.
To work around all this, we've created an SSH hosted shell app that allows for configuration of all of these items, but can't run it as a container on balenaOS because it needs a bind mount to /mnt/boot (in order to edit those files), but unfortunately "Bind mounts are not allowed" gets thrown during
balena push
, and based on this from @alexgg:I see that the supervisor can inject specific mounts at
balena-supervisor/src/compose/utils.ts
Line 314 in e01aaaa
io.balena.features.bootfs
. Maybe I could do this in the docker-compose:but that seems gross, and I'm not even sure every possible Balena image has
/mnt/boot
at/dev/sda1
.Am I missing something here or would the Balena team be open to a PR that provides an
io.balena.features.bootfs
entry to mount /mnt/boot into a container?The text was updated successfully, but these errors were encountered: