opiproject / sztp Goto Github PK
View Code? Open in Web Editor NEWSecure Zero Touch Provisioning (sZTP) in OPI
License: Apache License 2.0
Secure Zero Touch Provisioning (sZTP) in OPI
License: Apache License 2.0
not everybody wants to run in a container...
the correct flow is:
If the device is running a different image, the device downloads the image, uses the new image to upgrade, and then reboots with the new image.
today in the code the image is always
being downloaded
see
sztp/sztp-agent/pkg/secureagent/daemon.go
Line 55 in 2b14bd2
$ jq -r .\"ietf-sztp-bootstrap-server:output\".\"conveyed-information\" /tmp/post_rpc_input.json | base64 --decode | tail -n +2 | sed '1i {' | jq . | tee /tmp/post_rpc_fixed.json
{
"ietf-sztp-conveyed-info:onboarding-information": {
"boot-image": {
"download-uri": [
"http://web:8082/var/lib/misc/my-boot-image.img"
],
"image-verification": [
{
"hash-algorithm": "ietf-sztp-conveyed-info:sha-256",
"hash-value": "7b:ca:e6:ac:23:06:d8:79:06:8c:ac:03:80:e2:16:44:7e:40:6a:65:fa:d4:69:61:6e:05:ce:f5:87:dc:2b:97"
}
]
},
"pre-configuration-script": "Iy9iaW4vYmFzaAplY2hvICJpbnNpZGUgdGhlIHByZS1jb25maWd1cmF0aW9uLXNjcmlwdC4uLiIK",
"configuration-handling": "merge",
"configuration": "PHRvcCB4bWxucz0iaHR0cHM6L2V4YW1wbGUuY29tL2NvbmZpZyI+CiAgPGFueS14bWwtY29udGVudC1va2F5Lz4KPC90b3A+Cg==",
"post-configuration-script": "Iy9iaW4vYmFzaAplY2hvICJpbnNpZGUgdGhlIHBvc3QtY29uZmlndXJhdGlvbi1zY3JpcHQuLi4iCg=="
}
}
BUT what happens on first 2 lines ?
$ jq -r .\"ietf-sztp-bootstrap-server:output\".\"conveyed-information\" /tmp/post_rpc_input.json | base64 --decode | head -n 2
0▒B
*▒H▒▒+▒▒1▒-{
"ietf-sztp-conveyed-info:onboarding-information": {
to skip DHCP parsing
option sztp-redirect-urls "https://bootstrap:8080/restconf/operations/ietf-sztp-bootstrap-server:get-bootstrapping-data";
user may want to give direct option where the boostrap server is...
see code here to skip:
sztp/sztp-agent/pkg/secureagent/daemon.go
Line 43 in 5461c97
currently all of the readme and the .yml and config files are assuming running in a simulated environment. there needs to be a set of documentation that can be used with hardware. This may end up being a larger task with several smaller changes needing to be done. A decision should be made if we want each step to have a simulated environment example and a hardware based example, or if we want two documents; A simulated environment example, and a hardware environment example.
It appears that parts of the readme are outdated and showcase commands that do not work anymore.
To be specific, various sections show examples using the simulator
container, which does not exist anymore and was removed with Pull request #175 a few months ago (apparently the simulator is not needed anymore since the go implementation exists now).
The usage examples for the simulator should be removed or updated to show how the go implementation is to be used.
https://watsen.net/docs/sztpd/current/admin-guide/
cat << EOM > bootstrap-complete.json
{
"ietf-sztp-bootstrap-server:input" : {
"progress-type" : "bootstrap-complete",
"message" : "Dynamically generated SSH host key included.",
"ssh-host-keys" : {
"ssh-host-key" : [
{
"algorithm" : "ssh-rsa",
"key-data" : "BASE64VALUE="
}
]
}
}
}
EOM
# POST it to the "report-progress" RPC resource
curl -i -X POST --data @bootstrap-complete.json -H "Content-Type:application/yang-data+json" --cacert sbi_t\
rust_chain.pem --key pki/client/end-entity/private_key.pem --cert pki/client/end-entity/my_cert.pem --user \
my-serial-number:my-secret https://127.0.0.1:9090/restconf/operations/ietf-sztp-bootstrap-server:report-pro\
gress 1> output/post_progress_report.out 2>/dev/null
from spec:
The following example illustrates a device using the API to post a
progress report to a bootstrap server. Illustrated below is the
"bootstrap-complete" message, but the device may send other progress
reports to the server while bootstrapping. In this example, the
device is sending both its SSH host keys and a TLS server
certificate, which the bootstrap server may, for example, pass to an
NMS, as discussed in Appendix C.3.
REQUEST
[Note: ’\’ line wrapping for formatting only]
POST /restconf/operations/ietf-sztp-bootstrap-server:report-progress\
HTTP/1.1
HOST: example.com
Content-Type: application/yang.data+xml
<input xmlns="urn:ietf:params:xml:ns:yang:ietf-sztp-bootstrap-server">
<progress-type>bootstrap-complete</progress-type>
<message>example message</message>
<ssh-host-keys>
<ssh-host-key>
<algorithm>ssh-rsa</algorithm>
<key-data>base64encodedvalue==</key-data>
</ssh-host-key>
<ssh-host-key>
<algorithm>rsa-sha2-256</algorithm>
<key-data>base64encodedvalue==</key-data>
</ssh-host-key>
</ssh-host-keys>
<trust-anchor-certs>
<trust-anchor-cert>base64encodedvalue==</trust-anchor-cert>
</trust-anchor-certs>
</input>
RESPONSE
HTTP/1.1 204 No Content
Date: Sat, 31 Oct 2015 17:02:40 GMT
Server: example-server
example:
sztp-agent-1 | 2024/06/07 00:16:24 [INFO] Configuration file copied successfully
sztp-agent-1 | 2024/06/07 00:16:24 [INFO] Starting the pre-configuration.
sztp-agent-1 | 2024/06/07 00:16:24 [INFO] Starting the Report Progress request.
sztp-agent-1 | 2024/06/07 00:16:24 [INFO] Sending to: https://bootstrap:9090/restconf/operations/ietf-sztp-bootstrap-server:report-progress
sztp-agent-1 | 2024/06/07 00:16:24 [INFO] Sending input: {"ietf-sztp-bootstrap-server:input":{"progress-type":"pre-script-initiated","message":"message sent via JSON"}}
sztp-agent-1 | 2024/06/07 00:16:24 [ERROR] [ERROR] Status code received: 204 ...but status code expected: 200
sztp-agent-1 | 2024/06/07 00:16:24 [INFO] pre-configuration script created successfully
code
sztp/sztp-agent/pkg/secureagent/daemon.go
Line 99 in 5461c97
see
sztp/sztp-agent/pkg/secureagent/daemon.go
Line 223 in a1c2abf
and --insecure
flag from
Lines 39 to 41 in a1c2abf
Line 94 in a1c2abf
parse
"ietf-sztp-conveyed-info:onboarding-information": {
"boot-image": {
"download-uri": [
"http://web:8082/var/lib/misc/my-boot-image.img",
"ftp://web:3082/var/lib/misc/my-boot-image.img"
],
"image-verification": [
{
"hash-algorithm": "ietf-sztp-conveyed-info:sha-256",
"hash-value": "7b:ca:e6:ac:23:06:d8:79:06:8c:ac:03:80:e2:16:44:7e:40:6a:65:fa:d4:69:61:6e:05:ce:f5:87:dc:2b:97"
}
]
},
"pre-configuration-script": "IyEvYmluL2Jhc2gKZWNobyAiaW5zaWRlIHRoZSBwcmUtY29uZmlndXJhdGlvbi1zY3JpcHQuLi4iCg==",
"configuration-handling": "merge",
"configuration": "PHRvcCB4bWxucz0iaHR0cHM6L2V4YW1wbGUuY29tL2NvbmZpZyI+CiAgPGFueS14bWwtY29udGVudC1va2F5Lz4KPC90b3A+Cg==",
"post-configuration-script": "IyEvYmluL2Jhc2gKZWNobyAiaW5zaWRlIHRoZSBwb3N0LWNvbmZpZ3VyYXRpb24tc2NyaXB0Li4uIgo="
}
into
type BootstrapServerOnboardingIinformation struct {
BootImage struct {
DownloadURI []string `json:"download-uri"`
ImageVerification []struct {
HashAlgorithm string `json:"hash-algorithm"`
HashValue string `json:"hash-value"`
} `json:"image-verification"`
} `json:"boot-image"`
PreConfigurationScript string `json:"pre-configuration-script"`
ConfigurationHandling string `json:"configuration-handling"`
Configuration string `json:"configuration"`
PostConfigurationScript string `json:"post-configuration-script"`
}
here https://github.com/opiproject/sztp/blob/main/sztp-agent/pkg/secureAgent/daemon.go#L67
var oi BootstrapServerOnboardingIinformation
derr := json.Unmarshal(ci.Content.Bytes, &oi)
if derr != nil {
return derr
}
log.Println(oi)
in golang:
type AutoGenerated struct {
IetfSztpConveyedInfoRedirectInformation struct {
BootstrapServer []struct {
Address string `json:"address"`
Port int `json:"port"`
TrustAnchor string `json:"trust-anchor"`
} `json:"bootstrap-server"`
} `json:"ietf-sztp-conveyed-info:redirect-information"`
}
example:
{
"ietf-sztp-conveyed-info:redirect-information": {
"bootstrap-server": [
{
"address": "sztp1.example.com",
"port": 8443,
"trust-anchor": "base64encodedvalue=="
},
{
"address": "sztp2.example.com",
"port": 8443,
"trust-anchor": "base64encodedvalue=="
},
{
"address": "sztp3.example.com",
"port": 8443,
"trust-anchor": "base64encodedvalue=="
}
]
}
}
according to https://www.rfc-editor.org/rfc/pdfrfc/rfc8572.txt.pdf
6.1. Data Model Overview
The following tree diagram provides an overview of the data model for
the conveyed information artifact.
module: ietf-sztp-conveyed-info
yang-data conveyed-information:
+-- (information-type)
+--:(redirect-information)
| +-- redirect-information
| +-- bootstrap-server* [address]
| +-- address inet:host
| +-- port? inet:port-number
| +-- trust-anchor? cms
+--:(onboarding-information)
+-- onboarding-information
+-- boot-image
| +-- os-name? string
| +-- os-version? string
| +-- download-uri* inet:uri
| +-- image-verification* [hash-algorithm]
| +-- hash-algorithm identityref
| +-- hash-value yang:hex-string
+-- configuration-handling? enumeration
+-- pre-configuration-script? script
+-- configuration? binary
+-- post-configuration-script? script
from https://www.rfc-editor.org/rfc/pdfrfc/rfc8572.txt.pdf
7.1. API Overview
The following tree diagram provides an overview for the bootstrap server RESTCONF API.
module: ietf-sztp-bootstrap-server
rpcs:
+---x get-bootstrapping-data
| +---w input
| | +---w signed-data-preferred? empty
| | +---w hw-model? string
| | +---w os-name? string
| | +---w os-version? string
| | +---w nonce? binary
| +--ro output
| +--ro reporting-level? enumeration {onboarding-server}?
| +--ro conveyed-information cms
| +--ro owner-certificate? cms
| +--ro ownership-voucher? cms
+---x report-progress {onboarding-server}?
+---w input
+---w progress-type enumeration
+---w message? string
+---w ssh-host-keys
| +---w ssh-host-key* []
| +---w algorithm string
| +---w key-data binary
+---w trust-anchor-certs
+---w trust-anchor-cert* cms
go to https://github.com/orgs/opiproject/packages/container/opi-sztp-server/settings and remove it
in https://github.com/opiproject/sztp/blob/main/sztp-agent/pkg/secureAgent/daemon.go#L81
// TODO: download and verify OS image
log.Println(oi.IetfSztpConveyedInfoOnboardingInformation.BootImage.DownloadURI)
results in
2022/10/17 13:20:24 [http://web:8082/var/lib/misc/my-boot-image.img ftp://web:3082/var/lib/misc/my-boot-image.img]
so now please add file download like this
import ("net/http"; "io"; "os")
...
out, err := os.Create("output.txt")
defer out.Close()
...
resp, err := http.Get("http://example.com/")
defer resp.Body.Close()
...
n, err := io.Copy(out, resp.Body)
or like this
$ go get github.com/cavaliergopher/grab/v3
...
resp, err := grab.Get(".", "http://www.golang-book.com/public/pdf/gobook.pdf")
if err != nil {
log.Fatal(err)
}
fmt.Println("Download saved to", resp.Filename)
agent
containersper https://github.com/opiproject/opi-prov-life/blob/main/ZTP.md
we need IDEVID access, public/private keys, certificate, serial number to start SZTP process ...
see IEEE 802.1AR - Secure Device Identity
also see https://github.com/usnistgov/iDevIDCerts
@shachartal @mestery @prasunkapoor @rsb-oss @jainvipin @alknopfler @achilikin @gupta-alok ?
let's start the discussion here, on slack and on our next meeting
see 2 places
after adding certificates it stooped working
1 hack I already made is with regards to localhost
instead of
++ jq -r '."ietf-sztp-conveyed-info:onboarding-information"."boot-image"."download-uri"[]' /tmp/post_rpc_fixed.json
+ URL=http://web:8082/var/lib/misc/my-boot-image.img
++ basename http://web:8082/var/lib/misc/my-boot-image.img
+ docker-compose run --rm -v /tmp:/tmp agent curl --output /tmp/my-boot-image.img --fail http://web:8082/var/lib/misc/my-boot-image.img
Creating sztp_agent_run ... done
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 65536 100 65536 0 0 31.2M 0 --:--:-- --:--:-- --:--:-- 31.2M
++ awk '{print $2}'
+++ basename http://web:8082/var/lib/misc/my-boot-image.img
++ openssl dgst -sha256 -c /tmp/my-boot-image.img
+ SIGNATURE=7b:ca:e6:ac:23:06:d8:79:06:8c:ac:03:80:e2:16:44:7e:40:6a:65:fa:d4:69:61:6e:05:ce:f5:87:dc:2b:97
do
$ docker-compose run --rm -v /tmp:/tmp agent curl --output /tmp/my-boot-image.img --fail https://web:8082/var/lib/misc/my-boot-image.img
Creating sztp_agent_run ... done
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
ERROR: 35
see
sztp/sztp-agent/pkg/secureagent/daemon.go
Lines 103 to 105 in f969315
this is empty https://github.com/opiproject/sztp/blob/main/sztp-agent/pkg/secureagent/status.go
status
command should show where in the onboarding stage the device is right now...
for example: waiting on DHCP response...
or downloading file...
or pending reboot...
or provisioning was already completed...
or something else...
See this example:
https://cloudinit.readthedocs.io/en/latest/howto/status.html
maybe do do this, we need to create a file on the filesystem, like in example above, in /var/lib/sztp/result.json
and in /run/sztp/result.json
Post reboot, the entire SZTP sequence repeats, except that device doesn't reboot because it already has the required image.
On some systems docker-compose
does not work and you must use docker compose
. Assign this to me and I'll submit PR for the README. Issue created so I don't forget to do it once I get OCP demo finished
make a helper container that handles keys and mount volumes with keys to both client and server...
example
diff --git a/examples/sztp/config/input.json b/examples/sztp/config/input.json
index 1bdc36c..0236172 100644
--- a/examples/sztp/config/input.json
+++ b/examples/sztp/config/input.json
@@ -3,6 +3,7 @@
"hw-model" : "model-x",
"os-name" : "vendor-os",
"os-version" : "17.3R2.1",
+ "signed-data-preferred": [null],
"nonce" : "BASE64VALUE="
}
}
expect new fields in the response regarding owner
in addition to conveyed-information
, i.e.:
<output
xmlns="urn:ietf:params:xml:ns:yang:ietf-sztp-bootstrap-server">
<conveyed-information>base64encodedvalue==</conveyed-information>
<owner-certificate>base64encodedvalue==</owner-certificate>
<ownership-voucher>base64encodedvalue==</ownership-voucher>
</output>
also see the main RFC8572:
5.1. Initial State
+-------------------------------------------------------------+
| <device> |
| |
| +---------------------------------------------------------+ |
| | <read/write storage> | |
| | | |
| | 1. flag to enable SZTP bootstrapping set to "true" | |
| +---------------------------------------------------------+ |
| |
| +---------------------------------------------------------+ |
| | <read-only storage> | |
| | | |
| | 2. TLS client cert & related intermediate certificates | |
| | 3. list of trusted well-known bootstrap servers | |
| | 4. list of trust anchor certs for bootstrap servers | |
| | 5. list of trust anchor certs for ownership vouchers | |
| +---------------------------------------------------------+ |
| |
| +-----------------------------------------------------+ |
| | <secure storage> | |
| | | |
| | 6. private key for TLS client certificate | |
| | 7. private key for decrypting SZTP artifacts | |
| +-----------------------------------------------------+ |
| |
+-------------------------------------------------------------+
example
command: ['sztpd', 'postgresql://sztpd-admin:secret@localhost:5432/sztpd-db']
more documentation https://pypi.org/project/sztpd/
The "database-url" argument has the form "<dialect>:<dialect-specific-path>".
Three dialects are supported: "sqlite", "postgresql", and "mysql+pymysql".
The <dialect-specific-path> for each of these is described below.
For the "sqlite" dialect, <dialect-specific-path> follows the format
"///<sqlite-path>", where <sqlite-path> can be one of:
:memory: - an in-memory database (only useful for testing)
<filepath> - an OS-specific filepath to a persisted database file
Examples:
$ sztpd sqlite:///:memory: (memory)
$ sztpd sqlite:///relative/path/to/sztpd.db (unix)
$ sztpd sqlite:////absolute/path/to/sztpd.db (unix)
$ sztpd sqlite:///C:\path\to\sztpd.db (windows)
For both the "postgresql" and "mysql+pymysql" dialects, <dialect-specific-path>
follows the format "//<user>[:<passwd>]@<host>:<port>/<database-name>".
Examples:
The following two examples assume the database is called "sztpd" and
that the database server listens on the loopback address with no TLS.
$ sztpd mysql+pymysql://user:pass@localhost:3306/sztpd
$ sztpd postgresql://user:pass@localhost:5432/sztpd
Please see the documentation for more information.
see https://hub.docker.com/r/flungo/avahi
see https://github.com/hashicorp/mdns
$ docker run --rm -it flungo/avahi
Unable to find image 'flungo/avahi:latest' locally
latest: Pulling from flungo/avahi
596ba82af5aa: Pull complete
b206d7a30008: Pull complete
32376195e81b: Pull complete
Digest: sha256:1ca78a72b58f55565bdb585d00d1ab6168f35281616bde0e65c4bdead37f5ded
Status: Downloaded newer image for flungo/avahi:latest
Saved 1 file(s)
Found user 'avahi' (UID 86) and group 'avahi' (GID 86).
Successfully dropped root privileges.
avahi-daemon 0.8 starting up.
WARNING: No NSS support for mDNS detected, consider installing nss-mdns!
Successfully called chroot().
Successfully dropped remaining capabilities.
Loading service file /services/sftp-ssh.service.
Loading service file /services/ssh.service.
Joining mDNS multicast group on interface eth0.IPv6 with address 2001:db8:1::242:ac11:2.
New relevant interface eth0.IPv6 for mDNS.
Joining mDNS multicast group on interface eth0.IPv4 with address 172.17.0.2.
New relevant interface eth0.IPv4 for mDNS.
Joining mDNS multicast group on interface lo.IPv6 with address ::1.
New relevant interface lo.IPv6 for mDNS.
Joining mDNS multicast group on interface lo.IPv4 with address 127.0.0.1.
New relevant interface lo.IPv4 for mDNS.
Network interface enumeration completed.
Registering new address record for 2001:db8:1::242:ac11:2 on eth0.*.
Registering new address record for 172.17.0.2 on eth0.IPv4.
Registering new address record for ::1 on lo.*.
Registering new address record for 127.0.0.1 on lo.IPv4.
Server startup complete. Host name is b21a3cd25ae2.local. Local service cookie is 2413553038.
Service "b21a3cd25ae2" (/services/ssh.service) successfully established.
Service "b21a3cd25ae2" (/services/sftp-ssh.service) successfully established.
and
avahi-browse -v -a -t
or
$ docker-compose run nmap --script=dns-service-discovery
Starting Nmap 7.93 ( https://nmap.org ) at 2022-10-27 15:58 UTC
WARNING: No targets were specified, so 0 hosts scanned.
Nmap done: 0 IP addresses (0 hosts up) scanned in 0.24 seconds
Command "docker-compose build bootstrap" fails at step "Step 3/13 : RUN pip install --no-cache-dir sztpd==0.0.11" with:
Building wheels for collected packages: sztpd, pysqlite3, PyXB
Building wheel for sztpd (setup.py): started
Building wheel for sztpd (setup.py): finished with status 'done'
Created wheel for sztpd: filename=sztpd-0.0.11-py3-none-any.whl size=185835 sha256=ab578f2ae3765839e3e2a47911ee7ebcedce7236cee7a2be8d32e293af8e3631
Stored in directory: /tmp/pip-ephem-wheel-cache-cy2k2p_a/wheels/2c/a1/19/34f626cbfb76d0b61e1ff1a40501d2a69b262ef41125ca8397
Building wheel for pysqlite3 (setup.py): started
Building wheel for pysqlite3 (setup.py): finished with status 'error'
error: subprocess-exited-with-error
× python setup.py bdist_wheel did not run successfully.
│ exit code: 1
╰─> [15 lines of output]
running bdist_wheel
running build
running build_py
creating build
creating build/lib.linux-x86_64-cpython-310
creating build/lib.linux-x86_64-cpython-310/pysqlite3
copying pysqlite3/init.py -> build/lib.linux-x86_64-cpython-310/pysqlite3
copying pysqlite3/dbapi2.py -> build/lib.linux-x86_64-cpython-310/pysqlite3
running build_ext
Builds a C extension linking against libsqlite3 library
building 'pysqlite3._sqlite3' extension
creating build/temp.linux-x86_64-cpython-310
creating build/temp.linux-x86_64-cpython-310/src
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -DMODULE_NAME="pysqlite3.dbapi2" -I/usr/include -I/usr/local/include/python3.10 -c src/blob.c -o build/temp.linux-x86_64-cpython-310/src/blob.o
error: command 'gcc' failed: No such file or directory
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for pysqlite3
Adding gcc to the list of installed packages seems to fix the problem.
for make:
diff --git a/docker-compose.yml b/docker-compose.yml
index aaf88d6..ee45042 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -110,7 +110,8 @@ services:
echo "DNS.3 = web" >> sztpd1/sbi/end-entity/openssl.cnf
echo "DNS.4 = redirecter" >> sztpd1/sbi/end-entity/openssl.cnf
sed -i 's/my-serial-number/third-serial-number/g' client/end-entity/openssl.cnf
- make pki SHELL=/bin/ash
+ make -C sztpd1/sbi pki SHELL=/bin/ash
+ make -C client pki SHELL=/bin/ash
echo SERVER SBI certificates
cat sztpd1/sbi/end-entity/my_cert.pem sztpd1/sbi/intermediate2/my_cert.pem > /tmp/cert_chain.pem
openssl crl2pkcs7 -nocrl -certfile /tmp/cert_chain.pem -outform DER -out /tmp/cert_chain.cms
(END)
and for tar:
- tar -zxvf sztpd-simulator-0.0.11.tgz -C /tmp
+ tar -zxvf sztpd-simulator-0.0.11.tgz -C /tmp sztpd-simulator/pki/sztpd1/sbi sztpd-simulator/pki/client
today I see access-denied
error instead of input validation:
docker run --rm -it --network=host --mount type=bind,source=/mnt,target=/mnt --mount type=bind,source=/etc/os-release,target=/etc/os-release --mount type=bind,source=${DHCLIENT_LEASE_FILE},target=/var/lib/dhclient/dhclient.leases ghcr.io/opiproject/opi-sztp-client:v0.2.0 /opi-sztp-agent daemon --bootstrap-trust-anchor-cert /mnt/nonexist.pem --device-end-entity-cert /mnt/nonexist.pem --device-private-key /mnt/nonexist.pem --serial-number opi-serial-number
Run the daemon command
Usage:
opi-sztp-agent daemon [flags]
Flags:
--bootstrap-trust-anchor-cert string Bootstrap server trust anchor Cert (default "/certs/opi.pem")
--device-end-entity-cert string Device's End Entity cert (default "/certs/my_cert.pem")
--device-password string Device's password (default "my-secret")
--device-private-key string Device's private key (default "/certs/private_key.pem")
--dhcp-lease-file string Device's dhclient leases file (default "/var/lib/dhclient/dhclient.leases")
-h, --help help for daemon
--serial-number string Device's serial number (default "my-serial-number")
2024/06/17 13:04:09 [INFO] Get the Bootstrap URL from DHCP client
2024/06/17 13:04:09 [INFO] Bootstrap URL retrieved successfully: https://bootstrap:8080/restconf/operations/ietf-sztp-bootstrap-server:get-bootstrapping-data
2024/06/17 13:04:09 [INFO] Starting the Request to get On-boarding Information.
2024/06/17 13:04:09 [DEBUG] Sending to: https://bootstrap:8080/restconf/operations/ietf-sztp-bootstrap-server:get-bootstrapping-data
2024/06/17 13:04:09 [DEBUG] Sending input: {"ietf-sztp-bootstrap-server:input":{"hw-model":"BlueField SoC","os-name":"Ubuntu 22.04.4 LTS","os-version":"22.04","nonce":""}}
2024/06/17 13:04:09 [ERROR] [ERROR] Expected conveyed-information, received error type=protocol, tag=access-denied, message=
Error: [ERROR] Expected conveyed-information, received error type=protocol, tag=access-denied, message=
in /etc/dhcp/dhclient.conf
need to add:
option sztp-redirect-urls code 143 = text;
and request it
request subnet-mask, broadcast-address, ... , sztp-redirect-urls;
@pdp2shirts fyi
when running from external real dpu, need all relevant ports to be reachable, so expose them...
alternatively use host network...
see https://github.com/opiproject/opi-prov-life/blob/main/examples/sztp/README.md#device-getting-onboarding-information
we sending request from agent (client) so we need it there and not on the sztpd server
for example, if something is wrong with the POST request, this error can show, we need to parse it correctly and print log message
HTTP/1.1 404 Not Found
Content-Type: application/yang-data+json; charset=utf-8
Content-Length: 198
Date: Fri, 15 Jan 2021 02:38:07 GMT
Server: <redacted>
{
"ietf-restconf:errors": {
"error": [
{
"error-type": "application",
"error-tag": "data-missing",
"error-message": "No responses configured."
}
]
}
}
maybe download it and calculate signature or just remove from the docker image (think layers)
see example : https://github.com/jaypipes/ghw#baseboard
package main
import (
"fmt"
"github.com/jaypipes/ghw"
)
func main() {
baseboard, err := ghw.Baseboard()
if err != nil {
fmt.Printf("Error getting baseboard info: %v", err)
}
fmt.Printf("%v\n", baseboard)
}
https://github.com/jaypipes/ghw/blob/main/pkg/baseboard/baseboard_linux.go
https://github.com/jaypipes/ghw/blob/main/pkg/product/product_linux.go
we have only dhcpv4 now, let's add others...
see mdns example #108 (comment)
httpd config needed:
SSLVerifyClient require
SSLVerifyDepth 1
SSLCACertificateFile /etc/apache2/ssl/client.crt
sztpd fails to start with following stack:
sztp-bootstrap-1 | + sztpd sqlite:///:memory:
sztp-bootstrap-1 | Traceback (most recent call last):
sztp-bootstrap-1 | File "/usr/local/bin/sztpd", line 8, in
sztp-bootstrap-1 | sys.exit(main())
sztp-bootstrap-1 | File "/usr/local/lib/python3.10/site-packages/sztpd/main.py", line 5, in main
sztp-bootstrap-1 | def main(argv=None):A=argparse.ArgumentParser(prog='sztpd',formatter_class=argparse.RawDescriptionHelpFormatter,description='SZTPD implements the "bootstrap server" defined in RFC 8572.',epilog='\nExit status code: 0 on success, non-0 on error. Error output goes to stderr.\n\nThe "cacert" argument is a filepath to a PEM file that contains one or more X.509\nCA certificates used to authenticate the RDBMS's TLS certificate.\n\nThe "key" and "cert" arguments are each a filepath to a PEM file that contains\nthe key and certificate that SZTPD should use to authenticate itself to the\nRDBMS. These parameters must be specified together, and must be specified\nin conjunction with the "cacert" parameter.\n\nThe "database-url" argument has the form ":".\nThree dialects are supported: "sqlite", "postgresql", and "mysql+pymysql".\nThe dialect-specific-path for each of these is described below.\n\nFor the "sqlite" dialect, follows the format\n"///", where can be one of:\n\n :memory: - an in-memory database (only useful for testing)\n - an OS-specific filepath to a persisted database file\n\n Examples:\n\n $ sztpd sqlite:///:memory: (memory)\n $ sztpd sqlite:///relative/path/to/sztpd.db (unix)\n $ sztpd sqlite:////absolute/path/to/sztpd.db (unix)\n $ sztpd sqlite:///C:\path\to\sztpd.db (windows)\n\nFor both the "postgresql" and "mysql+pymysql" dialects, \nfollows the format "//[:]@:/".\n\n Examples:\n\n The following two examples assume the database is called "sztpd" and\n that the database server listens on the loopback address with no TLS.\n\n $ sztpd mysql+pymysql://user:pass@localhost:3306/sztpd\n $ sztpd postgresql://user:pass@localhost:5432/sztpd\n\n\nPlease see the documentation for more information.\n');A.add_argument('-v','--version',help='show version number and exit.',action='version',version=version.version);A.add_argument('-C','--cacert',help='path to certificates used to authenticate the database (see below for details).');A.add_argument('-c','--cert',help='path to cert used to authenticate SZTPD to the database (see below for details).');A.add_argument('-k','--key',help='path to key used to authenticate SZTPD to the database (see below for details).');A.add_argument('database_url',help='see below for details.',metavar='database-url');B=A.parse_args();return sztpd.run(B.database_url,B.cacert,B.cert,B.key)
sztp-bootstrap-1 | File "/usr/local/lib/python3.10/site-packages/sztpd/sztpd.py", line 54, in run
sztp-bootstrap-1 | except Exception as H:raise H;return 1
sztp-bootstrap-1 | File "/usr/local/lib/python3.10/site-packages/sztpd/sztpd.py", line 53, in run
sztp-bootstrap-1 | try:A=DataAccessLayer(O,J,K,L,json.loads(getattr(yl,'nbi_'+B)()),'wn-sztpd-'+B,B)
sztp-bootstrap-1 | File "/usr/local/lib/python3.10/site-packages/sztpd/yangcore/dal.py", line 79, in init
sztp-bootstrap-1 | else:A.app_ns=app_ns;A._create(B,C,D,E,F,opaque)
sztp-bootstrap-1 | File "/usr/local/lib/python3.10/site-packages/sztpd/yangcore/dal.py", line 660, in _create
sztp-bootstrap-1 | A.metadata=sa.MetaData(bind=A.engine,schema=A.db_schema);C=sa.Table(_G,A.metadata,sa.Column(_M,sa.Integer,primary_key=_E),sa.Column(_I,sa.Integer,unique=_E),sa.Column(F,sa.String(250),unique=_E),sa.Column(_O,jsob_type));A.metadata.create_all()
sztp-bootstrap-1 | TypeError: MetaData.init() got an unexpected keyword argument 'bind'
sztp-bootstrap-1 exited with code 1
MetaData bind argument is deprecated and will be removed from sqlalchemy2.0.0: https://github.com/sqlalchemy/sqlalchemy/blob/rel_1_4_46/lib/sqlalchemy/sql/schema.py#L4413-L4418
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates are awaiting their schedule. Click on a checkbox to get an update now.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
docker-compose.yml
docker.io/opiproject/sztpd 0.0.15
docker.io/opiproject/sztpd 0.0.15
docker.io/networkboot/dhcpd 1.3.0
docker.io/instrumentisto/nmap 7.94
docker.io/instrumentisto/nmap 7.94
docker.io/alpine/openssl 3.3.1
docker.io/library/httpd 2.4.57-alpine3.17
sztp-agent/Dockerfile
docker.io/library/golang 1.22.4-alpine
alpine 3.20
.github/workflows/codeql.yml
.github/workflows/commitlint.yml
.github/workflows/go.yml
actions/checkout v4
actions/setup-go v4
codecov/codecov-action v3
.github/workflows/linters.yml
actions/checkout v4
actions/checkout v4
hadolint/hadolint-action v3.1.0
actions/checkout v4
azohra/shell-linter v0.6.0
actions/checkout v4
ibiqlik/action-yamllint v3
actions/checkout v4
actions/setup-go v4
golangci/golangci-lint-action v3
.github/workflows/release-please.yml
.github/workflows/scorecard.yml
.github/workflows/sztp.yml
actions/checkout v4
docker/setup-qemu-action v3
docker/setup-buildx-action v3.0.0
docker/login-action v3.0.0
docker/login-action v3.0.0
docker/metadata-action v5.5.1
docker/build-push-action v5.4.0
actions/checkout v4
docker/setup-qemu-action v3
docker/setup-buildx-action abe89fb761023d1d963c81f6b5e0df54236dc097
.github/workflows/update-copyright-years-in-license-file.yml
sztp-agent/go.mod
go 1.19
github.com/TwiN/go-color v1.4.1
github.com/github/smimesign v0.2.0
github.com/jaypipes/ghw v0.12.0
github.com/spf13/cobra v1.7.0
golang.org/x/crypto v0.24.0
.pre-commit-config.yaml
pre-commit/pre-commit-hooks v4.5.0
renovatebot/pre-commit-hooks 37.415.0
alessandrojcm/commitlint-pre-commit-hook v9.16.0
golangci/golangci-lint v1.59.1
Use DHCP option 143 (IPv4) or 163 (IPv6), as described in RFC 8572
need changes here:
Line 24 in 302b5b7
See here:
sztp/sztp-agent/pkg/secureagent/daemon.go
Line 43 in 2b14bd2
there is no loop, DHCP response is processed and function returns...
We want to loop over interfaces and DHCP responses until bootstrap completes...
remove from
Line 23 in 7e76c59
it is used here
Line 35 in 7e76c59
and here
Line 50 in 7e76c59
and here
Line 56 in 7e76c59
can use compact form and send it inline like this?
curl -X POST --data {"ietf-sztp-bootstrap-server:input":{"progress-type":"bootstrap-initiated","message":"message sent via JSON"}} -H "Content-Type:application/yang-data+json" ...
curl -X POST --data {"ietf-sztp-bootstrap-server:input":{"hw-model":"model-x","os-name":"vendor-os","os-version":"17.3R2.1","signed-data-preferred":[null],"nonce":"BASE64VALUE="}} -H "Content-Type:application/yang-data+json" ...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.