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

osbuild: new stage 'cacert' (HMS-4839) #907

Merged
merged 4 commits into from
Nov 21, 2024
Merged

osbuild: new stage 'cacert' (HMS-4839) #907

merged 4 commits into from
Nov 21, 2024

Conversation

lzap
Copy link
Contributor

@lzap lzap commented Sep 5, 2024

This pull request adds a new stage called 'cacert' to the osbuild package. It also includes file changes to support the CACustomization feature, which allows users to specify a list of certificates for the CA (Certificate Authority). The changes include updates to the Customizations struct, the osCustomizations function, and the OSCustomizations struct. Additionally, a new function called parseCerts is added to parse the certificate strings. The changes also include updates to the serialize and prependKernelCmdlineStage functions in the OS struct. Finally, a new file called ca_stage.go is added to the osbuild package, which contains the implementation of the NewCAStageStage function.

Needs: osbuild/osbuild#1854

if len(p.CACerts) > 0 {
for _, cc := range p.CACerts {
for _, c := range parseCerts(cc) {
path := filepath.Join("/etc/pki/ca-trust/source/anchors", filepath.Base(c.SerialNumber.Text(16)))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing the filename extension, will add during review.

Copy link
Member

@achilleas-k achilleas-k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we break down this PR into multiple commits for easier reviewing and history?

I like to have commits that introduce new things separate from the following ones that use them, so maybe:

  1. Add osbuild/..._stage.go
  2. Add manifest/os.go changes.
  3. Add blueprint customization.
  4. Add config option to all-customizations.json.

(though, 2 and 3 can be merged).

@@ -32,6 +32,7 @@ type Customizations struct {
Installer *InstallerCustomization `json:"installer,omitempty" toml:"installer,omitempty"`
RPM *RPMCustomization `json:"rpm,omitempty" toml:"rpm,omitempty"`
RHSM *RHSMCustomization `json:"rhsm,omitempty" toml:"rhsm,omitempty"`
CA *CACustomization `json:"ca,omitempty" toml:"ca,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ca, while an accurate initialism and probably a very common term to refer to what we're doing, is probably not a great name for a configuration key in the soup of top-level blueprint customization names.

CertificateAuthority (certificate-authority) is, on the other hand, too long.

Maybe CACerts (toml:"ca-certs") would be a better name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, in the same struct I see a two-worded JSON field SSHKey as sshkey so I will stick with this theme and go for cacerts.

Comment on lines 177 to 178
"ca": [
"-----BEGIN CERTIFICATE-----\nMIIDszCCApugAwIBAgIUJ4lK+JfdJCNgcEVxZDinJfKKbQswDQYJKoZIhvcNAQEL\nBQAwaDELMAkGA1UEBhMCVVMxFzAVBgNVBAgMDk5vcnRoIENhcm9saW5hMRAwDgYD\nVQQHDAdSYWxlaWdoMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQDDBNUZXN0IENB\nIGZvciBvc2J1aWxkMCAXDTI0MDkwMzEzMjkyMFoYDzIyOTgwNjE4MTMyOTIwWjBo\nMQswCQYDVQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExEDAOBgNVBAcM\nB1JhbGVpZ2gxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAMME1Rlc3QgQ0EgZm9y\nIG9zYnVpbGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDeA7OcWTrV\ngstoBsUaeJKm8nelg7Lc0WNXH6yOTLsr4td4yHs0YOvFGwgSf+ffV3RAG1mgqnMG\nMgkD2+z+7QhHbHHs3y0d0zfhA2bg0KVvfCWk7fNRPHY0UOePpXk245Bfw3D0VTpl\nF7nePk1I7ZY09snPWUeb2rjKXzYjKjzM0h27+ykV8I8+FbdyPk/pR8whyDqtHLUa\nXfFy2TFloDSYMkHKVd38BnL0bj91x5F+KsZkN4HzfbYwxLbCQfOSgy7q6TWce9kq\nLo6tya9vuvpWFm1dye7L+BodAQAq/dI/JMeCfyTb0eFb+tyzfr5aVIoqqDN+p9ft\ncw4OefpHbhtNAgMBAAGjUzBRMB0GA1UdDgQWBBRV2A9YmusekPzu5Yf08cV0oPL1\nwjAfBgNVHSMEGDAWgBRV2A9YmusekPzu5Yf08cV0oPL1wjAPBgNVHRMBAf8EBTAD\nAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgQZ2Xfj+NxaKBZgn2KNxS0MTbhzHRz6Rn\nqJs+h8OUz2Crmaf6N+RHlmDRZXUrDjSHpxVT2LxFy7ofRrLYIezFDUYfb920VkkV\nSVcxh1YDFROJalfMoE6wdyR/LnK4MJZS9fUpeCJJc/A0J+9FK9CwcyUrHgJ8XbJh\nMKYyQ+cf6O7wzutuBpMyRqSKS+hVM7BQTmSFvv1eAJlo6klGAmmKiYmAEvcQadH1\ndjrujsA3Cn5vX2L+0yuiLB5/zoxqx5cEy97TuKUYB8OqMMujAXNzF4L3HJDUNba2\nAhEkFozMXwYX73TGbGZ0mawPS5D3v3tYTEmJFf6SnVCmUW1fs57g\n-----END CERTIFICATE-----\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't match the customization struct in the code. The way the customization is written now this should be:

"ca": {
  "certs": [
    "..."
  ]
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stage is called pki.update-ca-trust so please name the file accordingly for easier navigation.
pki_update_stage.go for example.

Copy link
Member

@achilleas-k achilleas-k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we break down this PR into multiple commits for easier reviewing and history?

I like to have commits that introduce new things separate from the following ones that use them, so maybe:

  1. Add osbuild/..._stage.go
  2. Add manifest/os.go changes.
  3. Add blueprint customization.
  4. Add config option to all-customizations.json.

(though, 2 and 3 can be merged).

@lzap
Copy link
Contributor Author

lzap commented Sep 9, 2024

Sure, amended all remarks. If you don’t mind, I am keeping one commit for easier work from my side, multiple commits rebasing is a pain to work with this isn’t a big PR by any means. I will split it after the code is ready.

Copy link

This PR is stale because it has been open 30 days with no activity. Remove "Stale" label or comment or this will be closed in 7 days.

@github-actions github-actions bot added the Stale label Oct 10, 2024
@mvo5 mvo5 removed the Stale label Oct 10, 2024
Copy link
Contributor

@mvo5 mvo5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this PR! It looks good but I still have some ideas/suggestions inline for your consideration. But I'm happy to help with them if you have no enough time :)

pkg/manifest/os.go Outdated Show resolved Hide resolved
pkg/manifest/os.go Outdated Show resolved Hide resolved
pkg/blueprint/customizations.go Outdated Show resolved Hide resolved
pkg/manifest/os.go Outdated Show resolved Hide resolved
@lzap
Copy link
Contributor Author

lzap commented Oct 14, 2024

I have extracted the checking code + test into separate package cert and implemented an explicit check method. No warnings but errors.

Copy link
Contributor

@mvo5 mvo5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update, looks very nice now, I made a suggestion inline, hope it's useful.

pkg/blueprint/customizations.go Outdated Show resolved Hide resolved
pkg/blueprint/customizations.go Outdated Show resolved Hide resolved
@@ -822,6 +826,25 @@ func (p *OS) serialize() osbuild.Pipeline {
}
}

if len(p.CACerts) > 0 {
for _, cc := range p.CACerts {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love to see a test for this but I understand this area is really difficult to test so fine to ignore that (but I also can't help to mention it)

@lzap
Copy link
Contributor Author

lzap commented Oct 23, 2024

Amended the recommended changes, fixed tests.

Let me know where and how to add a test for this.

REMINDER: For myself - the commit should be split as requested.

@lzap lzap force-pushed the cacerts1 branch 2 times, most recently from 7554a32 to 87a5bef Compare October 24, 2024 09:20
pkg/cert/parsecerts_test.go Show resolved Hide resolved
pkg/blueprint/customizations.go Outdated Show resolved Hide resolved
Copy link
Contributor

@mvo5 mvo5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good now from my PoV, one tiny suggestion about a test.

@lzap lzap force-pushed the cacerts1 branch 2 times, most recently from 5aec771 to f77ce5d Compare October 25, 2024 14:21
@lzap
Copy link
Contributor Author

lzap commented Oct 25, 2024

Rebased, hopefully it passes now.

@lzap
Copy link
Contributor Author

lzap commented Nov 4, 2024

Any other comments? I would love to get this in.

Copy link
Member

@achilleas-k achilleas-k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't feel too strongly about extracting the two lines into a function but the stage should be moved so that it's before the selinux one.

Comment on lines 836 to 843
for _, c := range certs {
path := filepath.Join("/etc/pki/ca-trust/source/anchors", filepath.Base(c.SerialNumber.Text(16))+".pem")
f, err := fsnode.NewFile(path, nil, "root", "root", pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: c.Raw}))
if err != nil {
panic(err)
}
pipeline.AddStages(osbuild.GenFileNodesStages([]*fsnode.File{f})...)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth extracting this into a helper function, just for easier reading?

Comment on lines 829 to 847
if len(p.CACerts) > 0 {
for _, cc := range p.CACerts {
certs, err := cert.ParseCerts(cc)
if err != nil {
panic(fmt.Errorf("failed to parse CA certificates: %v", err))
}

for _, c := range certs {
path := filepath.Join("/etc/pki/ca-trust/source/anchors", filepath.Base(c.SerialNumber.Text(16))+".pem")
f, err := fsnode.NewFile(path, nil, "root", "root", pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: c.Raw}))
if err != nil {
panic(err)
}
pipeline.AddStages(osbuild.GenFileNodesStages([]*fsnode.File{f})...)
}
}
pipeline.AddStage(osbuild.NewCAStageStage())
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this whole block up before the selinux stage is added (L798), so that any newly created files get labelled correctly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that is an excellent catch - thank you! Is there any way (not here probably) how we could detect this via tests (assuming we had a bit more test infra for manifest/os.go?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could, yeah.

@lzap
Copy link
Contributor Author

lzap commented Nov 4, 2024

I think the MTLS change kicked in and now breaking tests I need to fix this prior this PR:

internal/cloudapi/v2/server.go:231:55: cannot convert source (variable of type ostree.SourceSpec) to type worker.OSTreeResolveSpec

@lzap
Copy link
Contributor Author

lzap commented Nov 5, 2024

Moved, also I think I have found a good place for the CA file nodes code.

@lzap
Copy link
Contributor Author

lzap commented Nov 15, 2024

Thanks, that was helpful. It now generates fine.

@lzap lzap requested review from achilleas-k November 15, 2024 14:35
@lzap
Copy link
Contributor Author

lzap commented Nov 15, 2024

It looks like it works fine:

go run ./cmd/gen-manifests --distros rhel-9.5 --arches x86_64 --types qcow2 --config ./test/configs/all-customizations.json --output ./manifests --metadata=false

sudo osbuild ./manifests/rhel_9.5-x86_64-qcow2-all_customizations.json --export build --export os --export image --output-directory /tmp/osbuild-test --store /tmp/osbuild-test
lzap@dev:/tmp/osbuild-test/os/etc/pki/ca-trust/source/anchors$ cat 27894af897dd2423607045716438a725f28a6d0b.pem 
-----BEGIN CERTIFICATE-----
MIIDszCCApugAwIBAgIUJ4lK+JfdJCNgcEVxZDinJfKKbQswDQYJKoZIhvcNAQEL
BQAwaDELMAkGA1UEBhMCVVMxFzAVBgNVBAgMDk5vcnRoIENhcm9saW5hMRAwDgYD
VQQHDAdSYWxlaWdoMRAwDgYDVQQKDAdSZWQgSGF0MRwwGgYDVQQDDBNUZXN0IENB
IGZvciBvc2J1aWxkMCAXDTI0MDkwMzEzMjkyMFoYDzIyOTgwNjE4MTMyOTIwWjBo
MQswCQYDVQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExEDAOBgNVBAcM
B1JhbGVpZ2gxEDAOBgNVBAoMB1JlZCBIYXQxHDAaBgNVBAMME1Rlc3QgQ0EgZm9y
IG9zYnVpbGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDeA7OcWTrV
gstoBsUaeJKm8nelg7Lc0WNXH6yOTLsr4td4yHs0YOvFGwgSf+ffV3RAG1mgqnMG
MgkD2+z+7QhHbHHs3y0d0zfhA2bg0KVvfCWk7fNRPHY0UOePpXk245Bfw3D0VTpl
F7nePk1I7ZY09snPWUeb2rjKXzYjKjzM0h27+ykV8I8+FbdyPk/pR8whyDqtHLUa
XfFy2TFloDSYMkHKVd38BnL0bj91x5F+KsZkN4HzfbYwxLbCQfOSgy7q6TWce9kq
Lo6tya9vuvpWFm1dye7L+BodAQAq/dI/JMeCfyTb0eFb+tyzfr5aVIoqqDN+p9ft
cw4OefpHbhtNAgMBAAGjUzBRMB0GA1UdDgQWBBRV2A9YmusekPzu5Yf08cV0oPL1
wjAfBgNVHSMEGDAWgBRV2A9YmusekPzu5Yf08cV0oPL1wjAPBgNVHRMBAf8EBTAD
AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgQZ2Xfj+NxaKBZgn2KNxS0MTbhzHRz6Rn
qJs+h8OUz2Crmaf6N+RHlmDRZXUrDjSHpxVT2LxFy7ofRrLYIezFDUYfb920VkkV
SVcxh1YDFROJalfMoE6wdyR/LnK4MJZS9fUpeCJJc/A0J+9FK9CwcyUrHgJ8XbJh
MKYyQ+cf6O7wzutuBpMyRqSKS+hVM7BQTmSFvv1eAJlo6klGAmmKiYmAEvcQadH1
djrujsA3Cn5vX2L+0yuiLB5/zoxqx5cEy97TuKUYB8OqMMujAXNzF4L3HJDUNba2
AhEkFozMXwYX73TGbGZ0mawPS5D3v3tYTEmJFf6SnVCmUW1fs57g
-----END CERTIFICATE-----

@lzap lzap force-pushed the cacerts1 branch 3 times, most recently from ef85d5b to fb83fd4 Compare November 18, 2024 13:50
mvo5
mvo5 previously approved these changes Nov 18, 2024
Copy link
Contributor

@mvo5 mvo5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! This looks fine, I have some inline suggestions but no blockers, this seems all fine now. Thanks also for splitting it up.

pkg/osbuild/pki_update_ca_trust_stage_test.go Show resolved Hide resolved
for _, cc := range p.CACerts {
files, err := osbuild.NewCAFileNodes(cc)
if err != nil {
panic(err.Error())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(super nitpick) panic(err) would also work (and is slightly shorter)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a pattern in the whole file, I would rather not change it in this PR.

pkg/cert/parsecerts.go Show resolved Hide resolved
@@ -226,6 +226,14 @@ func osCustomizations(
osc.Files = append(osc.Files, imageConfig.Files...)
osc.Directories = append(osc.Directories, imageConfig.Directories...)

ca, err := c.GetCACerts()
if err != nil {
panic(fmt.Sprintf("unexpected error checking CA certs: %v", err))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I am not sure we should panic here, I see we do this a lot in this function whichI find confusing given that we have an error return here and that the certs come from the user so they maybe wrong and panic() seems a bit heavy handed for user inputs. But we can tweak in a followup given the rest of the function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

pkg/distro/rhel/images.go Show resolved Hide resolved
@lzap
Copy link
Contributor Author

lzap commented Nov 19, 2024

Rebased.

mvo5
mvo5 previously approved these changes Nov 19, 2024
Copy link
Contributor

@mvo5 mvo5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@lzap
Copy link
Contributor Author

lzap commented Nov 20, 2024

Forgot to run prepare-source.sh fixed, rebased.

@lzap lzap dismissed achilleas-k’s stale review November 21, 2024 07:57

Holidays, all the remarks were solved.

@mvo5 mvo5 added this pull request to the merge queue Nov 21, 2024
Merged via the queue into osbuild:main with commit b7bc37b Nov 21, 2024
19 checks passed
@lzap lzap deleted the cacerts1 branch November 21, 2024 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants