Skip to content
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

Extending read-only state to /sysroot and /boot #1265

Closed
cgwalters opened this issue Oct 12, 2017 · 13 comments
Closed

Extending read-only state to /sysroot and /boot #1265

cgwalters opened this issue Oct 12, 2017 · 13 comments

Comments

@cgwalters
Copy link
Member

cgwalters commented Oct 12, 2017

Today ostree has a ro bind mount over /usr, but one can just do e.g. rm -rf /sysroot/* and the whole system is destroyed.

Similarly, we tried to have support for /boot as a ro mount but it needs work.

What we should do is have these be ro by default, and then have apps using libostree create a new mount namespace, and make manipulations there. That way the system stays read-only to everything else. Alternatively, we could teach libostree how to do that internally, but it'd get ugly fast...we'd need to fork off a subprocess basically.

For example rpm-ostreed and eos-updater could change their systemd unit files to create a new mount namespace, and tell libostree that one is set up.

(Conceptually this overlaps a ton with systemd's ProtectSystem=strict...we're basically imposing that on the whole system by default)

@cgwalters
Copy link
Member Author

@giuseppe
Copy link
Member

would this be an issue for system containers that use /ostree/deploy/$OS_NAME/$DEST_FILE for creating hard links?

@cgwalters
Copy link
Member Author

@giuseppe an important bit from the above is:

...and then have apps using libostree create a new mount namespace, and make manipulations there.

The goal here isn't to make things truly immutable, it's to prevent things like restorecon -R / from destroying the system. And similar non-ostree-aware tools.

See also on-list discussion:

https://mail.gnome.org/archives/ostree-list/2017-December/msg00009.html

@giuseppe
Copy link
Member

I see, thanks. Could the new API allow also the current mount namespace to be used? It will be the user responsibility to ensure a new mount namespace is created and /sysroot can be remounted as writeable (and back to ro if needed).

@cgwalters
Copy link
Member Author

PR in #1767

cgwalters added a commit to cgwalters/ostree that referenced this issue Dec 25, 2018
We want to support extending the read-only state to cover `/sysroot`
and `/boot`, since conceptually all of the data there should only
be written via libostree.

This change needs to be opt-in though to avoid breaking anyone.

Add a `sysroot/readonly` key to the repository config which instructs
`ostree-remount.service` to ensure `/sysroot` is read-only.  This
requires a bit of a dance because `/sysroot` is actually the same
filesystem as `/`, which we can't mount readonly as we want `/etc`
to be writable (and `/var` if it's there too).  So we actually
make it into a bind mount.

Also add an API to instruct the libostree shared library
that the caller has created a new mount namespace.  This way
we can freely remount read-write.

This approach extends upon in a much better way previous work
we did to support remounting `/boot` read-write.

Closes: ostreedev#1265
cgwalters added a commit to cgwalters/ostree that referenced this issue Dec 26, 2018
We want to support extending the read-only state to cover `/sysroot`
and `/boot`, since conceptually all of the data there should only
be written via libostree.

This change needs to be opt-in though to avoid breaking anyone.

Add a `sysroot/readonly` key to the repository config which instructs
`ostree-remount.service` to ensure `/sysroot` is read-only.  This
requires a bit of a dance because `/sysroot` is actually the same
filesystem as `/`, which we can't mount readonly as we want `/etc`
to be writable (and `/var` if it's there too).  So we actually
make it into a bind mount.

Also add an API to instruct the libostree shared library
that the caller has created a new mount namespace.  This way
we can freely remount read-write.

This approach extends upon in a much better way previous work
we did to support remounting `/boot` read-write.

Closes: ostreedev#1265
cgwalters added a commit to cgwalters/fedora-coreos-config that referenced this issue Dec 26, 2018
Part of the implementation of ostreedev/ostree#1265

Convert to systemd mount units so we can easily specify the `ro` flag,
and also to use the `LABEL={root,var}` rather than UUIDs.

Enable the sysroot/readonly flag.
cgwalters added a commit to cgwalters/ignition-dracut that referenced this issue Dec 26, 2018
@cgwalters
Copy link
Member Author

Requirements to implement this for Fedora CoreOS:

coreos/fedora-coreos-config#39
coreos/ignition-dracut#36

cgwalters added a commit to cgwalters/ostree that referenced this issue Dec 26, 2018
We want to support extending the read-only state to cover `/sysroot`
and `/boot`, since conceptually all of the data there should only
be written via libostree.

This change needs to be opt-in though to avoid breaking anyone.

Add a `sysroot/readonly` key to the repository config which instructs
`ostree-remount.service` to ensure `/sysroot` is read-only.  This
requires a bit of a dance because `/sysroot` is actually the same
filesystem as `/`, which we can't mount readonly as we want `/etc`
to be writable (and `/var` if it's there too).  So we actually
make it into a bind mount.

Also add an API to instruct the libostree shared library
that the caller has created a new mount namespace.  This way
we can freely remount read-write.

This approach extends upon in a much better way previous work
we did to support remounting `/boot` read-write.

Closes: ostreedev#1265
cgwalters added a commit to cgwalters/ostree that referenced this issue Dec 29, 2018
We want to support extending the read-only state to cover `/sysroot`
and `/boot`, since conceptually all of the data there should only
be written via libostree.

This change needs to be opt-in though to avoid breaking anyone.

Add a `sysroot/readonly` key to the repository config which instructs
`ostree-remount.service` to ensure `/sysroot` is read-only.  This
requires a bit of a dance because `/sysroot` is actually the same
filesystem as `/`, which we can't mount readonly as we want `/etc`
to be writable (and `/var` if it's there too).  So we actually
make it into a bind mount.

Also add an API to instruct the libostree shared library
that the caller has created a new mount namespace.  This way
we can freely remount read-write.

This approach extends upon in a much better way previous work
we did to support remounting `/boot` read-write.

Closes: ostreedev#1265
cgwalters added a commit to cgwalters/ignition-dracut that referenced this issue Jan 3, 2019
cgwalters added a commit to cgwalters/ostree that referenced this issue Mar 23, 2019
We want to support extending the read-only state to cover `/sysroot`
and `/boot`, since conceptually all of the data there should only
be written via libostree.

This change needs to be opt-in though to avoid breaking anyone.

Add a `sysroot/readonly` key to the repository config which instructs
`ostree-remount.service` to ensure `/sysroot` is read-only.  This
requires a bit of a dance because `/sysroot` is actually the same
filesystem as `/`, which we can't mount readonly as we want `/etc`
to be writable (and `/var` if it's there too).  So we actually
make it into a bind mount.

Also add an API to instruct the libostree shared library
that the caller has created a new mount namespace.  This way
we can freely remount read-write.

This approach extends upon in a much better way previous work
we did to support remounting `/boot` read-write.

Closes: ostreedev#1265
@jlebon
Copy link
Member

jlebon commented Apr 18, 2019

Yeah, we really should fix this. Right now, restorecon -R / and autorelabel=1 are super dangerous (see e.g. user report at https://twitter.com/goozbach/status/1118697493657681920?s=19).

To anyone in that situation, you can recover from this by booting with enforcing=0, then:

# rpm-ostree status -v # copy "BaseCommit" or if missing, "Commit"
# ostree checkout -H $checksum /ostree/repo/tmp/selinux-fix
# ostree fsck --delete
# ostree commit --consume --link-checkout-speedup --orphan --selinux-policy=/ /ostree/repo/tmp/selinux-fix
# restorecon -Rv /var
# restorecon -Rv /etc
# ostree admin deploy fedora-atomic:fedora/29/x86_64/atomic-host # or whatever refspec you're on
# reboot

At this point, you should be able to boot in enforcing mode again. Final cleanup:

# rpm-ostree cleanup --rollback

Note this will blow away all your layered packages; you'll have to relayer those again.

@goozbach
Copy link

should that be BaseCommit or Commit instead of checksum?

@jlebon
Copy link
Member

jlebon commented Apr 18, 2019

Thanks! I edited the original comment.

@goozbach
Copy link

For future reference I had to do an rpm-ostree upgrade prior to the above steps for them to work.

Other than that, this workaround is good!

cgwalters added a commit to cgwalters/ostree that referenced this issue Aug 30, 2019
We want to support extending the read-only state to cover `/sysroot`
and `/boot`, since conceptually all of the data there should only
be written via libostree.

This change needs to be opt-in though to avoid breaking anyone.

Add a `sysroot/readonly` key to the repository config which instructs
`ostree-remount.service` to ensure `/sysroot` is read-only.  This
requires a bit of a dance because `/sysroot` is actually the same
filesystem as `/`, which we can't mount readonly as we want `/etc`
to be writable (and `/var` if it's there too).  So we actually
make it into a bind mount.

Also add an API to instruct the libostree shared library
that the caller has created a new mount namespace.  This way
we can freely remount read-write.

This approach extends upon in a much better way previous work
we did to support remounting `/boot` read-write.

Closes: ostreedev#1265
cgwalters added a commit to cgwalters/ostree that referenced this issue Sep 3, 2019
We want to support extending the read-only state to cover `/sysroot`
and `/boot`, since conceptually all of the data there should only
be written via libostree.

This change needs to be opt-in though to avoid breaking anyone.

Add a `sysroot/readonly` key to the repository config which instructs
`ostree-remount.service` to ensure `/sysroot` is read-only.  This
requires a bit of a dance because `/sysroot` is actually the same
filesystem as `/`; so we make `/etc` a writable bind mount in this case.

We also need to handle `/var` in the "OSTree default" case of a bind
mount; the systemd generator now looks at the writability state of
`/sysroot` and uses that to determine whether it should have the
`var.mount` unit happen before or after `ostree-remount.service.`

Also add an API to instruct the libostree shared library
that the caller has created a new mount namespace.  This way
we can freely remount read-write.

This approach extends upon in a much better way previous work
we did to support remounting `/boot` read-write.

Closes: ostreedev#1265
cgwalters added a commit to cgwalters/ostree that referenced this issue Sep 3, 2019
We want to support extending the read-only state to cover `/sysroot`
and `/boot`, since conceptually all of the data there should only
be written via libostree.

This change needs to be opt-in though to avoid breaking anyone.

Add a `sysroot/readonly` key to the repository config which instructs
`ostree-remount.service` to ensure `/sysroot` is read-only.  This
requires a bit of a dance because `/sysroot` is actually the same
filesystem as `/`; so we make `/etc` a writable bind mount in this case.

We also need to handle `/var` in the "OSTree default" case of a bind
mount; the systemd generator now looks at the writability state of
`/sysroot` and uses that to determine whether it should have the
`var.mount` unit happen before or after `ostree-remount.service.`

Also add an API to instruct the libostree shared library
that the caller has created a new mount namespace.  This way
we can freely remount read-write.

This approach extends upon in a much better way previous work
we did to support remounting `/boot` read-write.

Closes: ostreedev#1265
cgwalters added a commit to cgwalters/ostree that referenced this issue Sep 5, 2019
Prep for using the default mount namespace handling there that
will land as part of the read-only `/sysroot` and `/boot` work.
See ostreedev#1265
cgwalters added a commit to cgwalters/ostree that referenced this issue Sep 16, 2019
We want to support extending the read-only state to cover `/sysroot`
and `/boot`, since conceptually all of the data there should only
be written via libostree.

This change needs to be opt-in though to avoid breaking anyone.

Add a `sysroot/readonly` key to the repository config which instructs
`ostree-remount.service` to ensure `/sysroot` is read-only.  This
requires a bit of a dance because `/sysroot` is actually the same
filesystem as `/`; so we make `/etc` a writable bind mount in this case.

We also need to handle `/var` in the "OSTree default" case of a bind
mount; the systemd generator now looks at the writability state of
`/sysroot` and uses that to determine whether it should have the
`var.mount` unit happen before or after `ostree-remount.service.`

Also add an API to instruct the libostree shared library
that the caller has created a new mount namespace.  This way
we can freely remount read-write.

This approach extends upon in a much better way previous work
we did to support remounting `/boot` read-write.

Closes: ostreedev#1265
cgwalters added a commit to cgwalters/ostree that referenced this issue Nov 8, 2019
Prep for using the default mount namespace handling there that
will land as part of the read-only `/sysroot` and `/boot` work.
See ostreedev#1265
cgwalters added a commit to cgwalters/ostree that referenced this issue Nov 8, 2019
We want to support extending the read-only state to cover `/sysroot`
and `/boot`, since conceptually all of the data there should only
be written via libostree.

This change needs to be opt-in though to avoid breaking anyone.

Add a `sysroot/readonly` key to the repository config which instructs
`ostree-remount.service` to ensure `/sysroot` is read-only.  This
requires a bit of a dance because `/sysroot` is actually the same
filesystem as `/`; so we make `/etc` a writable bind mount in this case.

We also need to handle `/var` in the "OSTree default" case of a bind
mount; the systemd generator now looks at the writability state of
`/sysroot` and uses that to determine whether it should have the
`var.mount` unit happen before or after `ostree-remount.service.`

Also add an API to instruct the libostree shared library
that the caller has created a new mount namespace.  This way
we can freely remount read-write.

This approach extends upon in a much better way previous work
we did to support remounting `/boot` read-write.

Closes: ostreedev#1265
cgwalters added a commit to cgwalters/coreos-assembler that referenced this issue Nov 8, 2019
Let's opt-in to this by default.
See ostreedev/ostree#1265

This currently is a no-op if the required ostree support hasn't
landed yet, so I think we can safely merge this PR first.
cgwalters added a commit to cgwalters/ostree that referenced this issue Nov 8, 2019
We want to support extending the read-only state to cover `/sysroot`
and `/boot`, since conceptually all of the data there should only
be written via libostree.  Or at least for `/boot` should *mostly*
just be written by ostree.

This change needs to be opt-in though to avoid breaking anyone.

Add a `sysroot/readonly` key to the repository config which instructs
`ostree-remount.service` to ensure `/sysroot` is read-only.  This
requires a bit of a dance because `/sysroot` is actually the same
filesystem as `/`; so we make `/etc` a writable bind mount in this case.

We also need to handle `/var` in the "OSTree default" case of a bind
mount; the systemd generator now looks at the writability state of
`/sysroot` and uses that to determine whether it should have the
`var.mount` unit happen before or after `ostree-remount.service.`

Also add an API to instruct the libostree shared library
that the caller has created a new mount namespace.  This way
we can freely remount read-write.

This approach extends upon in a much better way previous work
we did to support remounting `/boot` read-write.

Closes: ostreedev#1265
cgwalters added a commit to cgwalters/ostree that referenced this issue Nov 10, 2019
We want to support extending the read-only state to cover `/sysroot`
and `/boot`, since conceptually all of the data there should only
be written via libostree.  Or at least for `/boot` should *mostly*
just be written by ostree.

This change needs to be opt-in though to avoid breaking anyone.

Add a `sysroot/readonly` key to the repository config which instructs
`ostree-remount.service` to ensure `/sysroot` is read-only.  This
requires a bit of a dance because `/sysroot` is actually the same
filesystem as `/`; so we make `/etc` a writable bind mount in this case.

We also need to handle `/var` in the "OSTree default" case of a bind
mount; the systemd generator now looks at the writability state of
`/sysroot` and uses that to determine whether it should have the
`var.mount` unit happen before or after `ostree-remount.service.`

Also add an API to instruct the libostree shared library
that the caller has created a new mount namespace.  This way
we can freely remount read-write.

This approach extends upon in a much better way previous work
we did to support remounting `/boot` read-write.

Closes: ostreedev#1265
cgwalters added a commit to cgwalters/ostree that referenced this issue Dec 11, 2019
Prep for using the default mount namespace handling there that
will land as part of the read-only `/sysroot` and `/boot` work.
See ostreedev#1265
cgwalters added a commit to cgwalters/coreos-assembler that referenced this issue Dec 11, 2019
Let's opt-in to this by default.
See ostreedev/ostree#1265

This currently is a no-op if the required ostree support hasn't
landed yet, so I think we can safely merge this PR first.
cgwalters added a commit to cgwalters/coreos-assembler that referenced this issue Dec 11, 2019
Let's opt-in to this by default.
See ostreedev/ostree#1265

This currently is a no-op if the required ostree support hasn't
landed yet, so I think we can safely merge this PR first.
cgwalters added a commit to cgwalters/rpm-ostree that referenced this issue Dec 11, 2019
This is all we need to tell libostree that we support a read-only
`/sysroot` and `/boot`.

See ostreedev/ostree#1265
PR in ostreedev/ostree#1767
jlebon pushed a commit to coreos/coreos-assembler that referenced this issue Dec 11, 2019
Let's opt-in to this by default.
See ostreedev/ostree#1265

This currently is a no-op if the required ostree support hasn't
landed yet, so I think we can safely merge this PR first.
cgwalters added a commit to cgwalters/rpm-ostree that referenced this issue Dec 11, 2019
This is all we need to tell libostree that we support a read-only
`/sysroot` and `/boot`.

See ostreedev/ostree#1265
PR in ostreedev/ostree#1767
cgwalters added a commit to cgwalters/rpm-ostree that referenced this issue Dec 12, 2019
This is all we need to tell libostree that we support a read-only
`/sysroot` and `/boot`.

See ostreedev/ostree#1265
PR in ostreedev/ostree#1767
cgwalters added a commit to cgwalters/rpm-ostree that referenced this issue Dec 12, 2019
This is all we need to tell libostree that we support a read-only
`/sysroot` and `/boot`.

See ostreedev/ostree#1265
PR in ostreedev/ostree#1767
cgwalters added a commit to cgwalters/rpm-ostree that referenced this issue Dec 12, 2019
This is all we need to tell libostree that we support a read-only
`/sysroot` and `/boot`.

See ostreedev/ostree#1265
PR in ostreedev/ostree#1767
jlebon pushed a commit to cgwalters/rpm-ostree that referenced this issue Dec 12, 2019
This is all we need to tell libostree that we support a read-only
`/sysroot` and `/boot`.

See ostreedev/ostree#1265
PR in ostreedev/ostree#1767
openshift-merge-robot pushed a commit to coreos/rpm-ostree that referenced this issue Dec 13, 2019
This is all we need to tell libostree that we support a read-only
`/sysroot` and `/boot`.

See ostreedev/ostree#1265
PR in ostreedev/ostree#1767
jlebon added a commit to jlebon/fedora-coreos-config that referenced this issue Mar 16, 2020
We want to use the new read-only `/sysroot` feature of libostree. Opt-in
to that to tell cosa we support it and want it.

For more details, see:
ostreedev/ostree#1265
coreos/coreos-assembler#1235
jlebon added a commit to jlebon/fedora-coreos-config that referenced this issue Mar 16, 2020
We want to use the new read-only `/sysroot` feature of libostree. Opt-in
to that to tell cosa we support it and want it.

For more details, see:
ostreedev/ostree#1265
coreos/coreos-assembler#1235
@bam80
Copy link

bam80 commented Apr 21, 2020

Yeah, we really should fix this. Right now, restorecon -R / and autorelabel=1 are super dangerous

I still broke my Fedora Silverblue 31 system with restorecon -R / command. Isn't it fixed yet?

@jlebon
Copy link
Member

jlebon commented Apr 21, 2020

I still broke my Fedora Silverblue 31 system with restorecon -R / command. Isn't it fixed yet?

OSTree knows how to handle read-only /sysroot, but it doesn't automatically apply to existing nodes, because it requires modifying files not maintained by updates. We'll probably need a systemd service in fedora-release-silverblue or something to transition over existing systems.

@bam80
Copy link

bam80 commented Apr 21, 2020

Thanks @jlebon. Could we dedicate a separate issue for that part of the task then?

cgwalters pushed a commit to jlebon/fedora-coreos-config that referenced this issue May 18, 2020
We want to use the new read-only `/sysroot` feature of libostree. Opt-in
to that to tell cosa we support it and want it.

For more details, see:
ostreedev/ostree#1265
coreos/coreos-assembler#1235
ashcrow pushed a commit to coreos/fedora-coreos-config that referenced this issue May 18, 2020
We want to use the new read-only `/sysroot` feature of libostree. Opt-in
to that to tell cosa we support it and want it.

For more details, see:
ostreedev/ostree#1265
coreos/coreos-assembler#1235
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants