Skip to content

Commit e11f7e9

Browse files
Strict patch
1 parent 85e73c1 commit e11f7e9

77 files changed

Lines changed: 1146 additions & 269 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build-snap.yml

Lines changed: 74 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
name: Build MicroK8s snap on PR and push to master
22

33
on:
4-
push:
5-
branches:
6-
- master
7-
pull_request:
8-
branches:
9-
- master
4+
- push
5+
- pull_request
6+
7+
### While we work on the strict feature we want the tests to run even if we do put PRs against the master.
8+
### When this work get merged into master the following should be commented in.
9+
# push:
10+
# branches:
11+
# - master
12+
# pull_request:
13+
# branches:
14+
# - master
1015

1116
jobs:
1217
build:
@@ -43,24 +48,80 @@ jobs:
4348
- name: Running upgrade path test
4449
run: |
4550
set -x
46-
sudo -E UPGRADE_MICROK8S_FROM=latest/edge UPGRADE_MICROK8S_TO=`pwd`/`ls microk8s*.snap` pytest -s ./tests/test-upgrade-path.py
47-
sudo snap remove microk8s --purge
48-
- name: Running addons tests
51+
# Remove the snapd refresh as soon as v2.52 lands
52+
sudo snap refresh snapd --channel=latest/edge
53+
- name: Check branches
54+
run: |
55+
set -x
56+
(cd tests; pytest -s verify-branches.py)
57+
- name: Running addons tests in strict mode
4958
run: |
5059
set -x
51-
sudo snap install *.snap --classic --dangerous
60+
sudo snap install microk8s.snap --dangerous
61+
sudo ./tests/connect-all-interfaces.sh
5262
./tests/smoke-test.sh
5363
export UNDER_TIME_PRESSURE="True"
64+
export SKIP_OPENEBS="True"
5465
export SKIP_PROMETHEUS="False"
5566
(cd tests; pytest -s verify-branches.py)
5667
sudo -E bash -c "cd /var/snap/microk8s/common/addons/core/tests; pytest -s -ra test-addons.py"
5768
sudo microk8s enable community
5869
sudo -E bash -c "cd /var/snap/microk8s/common/addons/community/tests; pytest -s -ra test-addons.py"
70+
grep -Po "Report tarball is at \K.+" |
71+
sudo xargs -I {} mv {} inspection-report-strict-${{ strategy.job-index }}.tar.gz
5972
sudo snap remove microk8s --purge
60-
- name: Running upgrade tests
73+
sudo rm -rf $HOME/.kube
74+
sudo rm -rf $HOME/.config/helm
75+
sudo dmesg | grep 'apparmor="DENIED"' > ./denials-${{ strategy.job-index }}.log
76+
- name: Upload strict inspect tarball
77+
uses: actions/upload-artifact@v2
78+
with:
79+
name: inspection-report-strict-actions
80+
path: ./inspection-report-strict-${{ strategy.job-index }}.tar.gz
81+
- name: Upload AppArmor denials
82+
uses: actions/upload-artifact@v2
83+
with:
84+
name: apparmor-denials
85+
path: ./denials-${{ strategy.job-index }}.log
86+
- name: Running addons tests in devmode
6187
run: |
6288
set -x
63-
sudo snap install *.snap --classic --dangerous
89+
################ Until devmode of docker-support is fixed we skip this part of the tests #######
90+
exit 0
91+
sudo snap install microk8s.snap --devmode --dangerous
92+
sudo ./tests/connect-all-interfaces.sh
93+
./tests/smoke-test.sh
6494
export UNDER_TIME_PRESSURE="True"
65-
sudo -E bash -c "cd /var/snap/microk8s/common/addons/core/ ; UPGRADE_MICROK8S_FROM=latest/edge UPGRADE_MICROK8S_TO=`pwd`/`ls microk8s*.snap` pytest -s ./tests/test-upgrade.py"
95+
export SKIP_OPENEBS="False"
96+
export SKIP_PROMETHEUS="False"
97+
(cd tests; sudo -E pytest -s -ra test-addons.py)
98+
sudo microk8s inspect |
99+
grep -Po "Report tarball is at \K.+" |
100+
sudo xargs -I {} mv {} inspection-report-devmode-${{ strategy.job-index }}.tar.gz
66101
sudo snap remove microk8s --purge
102+
- name: Upload devmode inspect tarball
103+
uses: actions/upload-artifact@v2
104+
with:
105+
name: inspection-report-devmode-actions
106+
path: ./inspection-report-devmode-${{ strategy.job-index }}.tar.gz
107+
- name: Generate AppArmor on failure
108+
run: sudo dmesg | grep 'apparmor="DENIED"' > ./denials-${{ strategy.job-index }}.log
109+
if: failure()
110+
- name: Upload AppArmor denials failure
111+
uses: actions/upload-artifact@v2
112+
with:
113+
name: apparmor-denials
114+
path: ./denials-${{ strategy.job-index }}.log
115+
if: failure()
116+
- name: Generate inspect tarball
117+
run: >
118+
sudo microk8s inspect |
119+
grep -Po "Report tarball is at \K.+" |
120+
sudo xargs -I {} mv {} inspection-report-fail-${{ strategy.job-index }}.tar.gz
121+
if: failure()
122+
- name: Upload inspect tarball
123+
uses: actions/upload-artifact@v2
124+
with:
125+
name: inspection-report-actions
126+
path: ./inspection-report-fail-${{ strategy.job-index }}.tar.gz
127+
if: failure()
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
From 08607d16c6f9ef393e18e0f62fcd967e91c5f7c9 Mon Sep 17 00:00:00 2001
2+
From: Alberto Mardegan <mardy@users.sourceforge.net>
3+
Date: Wed, 16 Jun 2021 15:04:16 +0300
4+
Subject: [PATCH 1/3] apparmor: change profile immediately, not on exec
5+
6+
---
7+
libcontainer/apparmor/apparmor_linux.go | 8 ++++----
8+
1 file changed, 4 insertions(+), 4 deletions(-)
9+
10+
diff --git a/libcontainer/apparmor/apparmor_linux.go b/libcontainer/apparmor/apparmor_linux.go
11+
index 5da14fb3..93ede183 100644
12+
--- a/libcontainer/apparmor/apparmor_linux.go
13+
+++ b/libcontainer/apparmor/apparmor_linux.go
14+
@@ -49,9 +49,9 @@ func setProcAttr(attr, value string) error {
15+
return err
16+
}
17+
18+
-// changeOnExec reimplements aa_change_onexec from libapparmor in Go
19+
-func changeOnExec(name string) error {
20+
- if err := setProcAttr("exec", "exec "+name); err != nil {
21+
+// changeProfile reimplements aa_change_profile from libapparmor in Go
22+
+func changeProfile(name string) error {
23+
+ if err := setProcAttr("current", "changeprofile "+name); err != nil {
24+
return fmt.Errorf("apparmor failed to apply profile: %s", err)
25+
}
26+
return nil
27+
@@ -64,5 +64,5 @@ func ApplyProfile(name string) error {
28+
return nil
29+
}
30+
31+
- return changeOnExec(name)
32+
+ return changeProfile(name)
33+
}
34+
--
35+
2.25.1
36+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
From 66fd3c5129599834de8262ee90a1ab2bf6b68ff0 Mon Sep 17 00:00:00 2001
2+
From: Alberto Mardegan <mardy@users.sourceforge.net>
3+
Date: Wed, 16 Jun 2021 15:04:40 +0300
4+
Subject: [PATCH 2/3] setns_init_linux: set the NNP flag after changing the
5+
apparmor profile
6+
7+
With the current version of the AppArmor kernel module, it's not
8+
possible to switch the AppArmor profile if the NoNewPrivileges flag is
9+
set. So, we invert the order of the two operations.
10+
---
11+
libcontainer/setns_init_linux.go | 10 +++++-----
12+
1 file changed, 5 insertions(+), 5 deletions(-)
13+
14+
diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go
15+
index 97987f1d..eec427a0 100644
16+
--- a/libcontainer/setns_init_linux.go
17+
+++ b/libcontainer/setns_init_linux.go
18+
@@ -57,11 +57,6 @@ func (l *linuxSetnsInit) Init() error {
19+
return err
20+
}
21+
}
22+
- if l.config.NoNewPrivileges {
23+
- if err := unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
24+
- return err
25+
- }
26+
- }
27+
if err := selinux.SetExecLabel(l.config.ProcessLabel); err != nil {
28+
return err
29+
}
30+
@@ -80,6 +75,11 @@ func (l *linuxSetnsInit) Init() error {
31+
if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil {
32+
return err
33+
}
34+
+ if l.config.NoNewPrivileges {
35+
+ if err := unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
36+
+ return err
37+
+ }
38+
+ }
39+
// Set seccomp as close to execve as possible, so as few syscalls take
40+
// place afterward (reducing the amount of syscalls that users need to
41+
// enable in their seccomp profiles).
42+
--
43+
2.25.1
44+
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
From 728d989c7643a87ca9d57e3135e35c7af833bae0 Mon Sep 17 00:00:00 2001
2+
From: Alberto Mardegan <mardy@users.sourceforge.net>
3+
Date: Thu, 17 Jun 2021 14:31:35 +0300
4+
Subject: [PATCH 3/3] standard_init_linux: change AppArmor profile as late as
5+
possible
6+
7+
---
8+
libcontainer/standard_init_linux.go | 18 +++++++++---------
9+
1 file changed, 9 insertions(+), 9 deletions(-)
10+
11+
diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go
12+
index d77022ad..6f43da5f 100644
13+
--- a/libcontainer/standard_init_linux.go
14+
+++ b/libcontainer/standard_init_linux.go
15+
@@ -114,10 +114,6 @@ func (l *linuxStandardInit) Init() error {
16+
return errors.Wrap(err, "sethostname")
17+
}
18+
}
19+
- if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil {
20+
- return errors.Wrap(err, "apply apparmor profile")
21+
- }
22+
-
23+
for key, value := range l.config.Config.Sysctl {
24+
if err := writeSystemProperty(key, value); err != nil {
25+
return errors.Wrapf(err, "write sysctl key %s", key)
26+
@@ -137,17 +133,21 @@ func (l *linuxStandardInit) Init() error {
27+
if err != nil {
28+
return errors.Wrap(err, "get pdeath signal")
29+
}
30+
- if l.config.NoNewPrivileges {
31+
- if err := unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
32+
- return errors.Wrap(err, "set nonewprivileges")
33+
- }
34+
- }
35+
// Tell our parent that we're ready to Execv. This must be done before the
36+
// Seccomp rules have been applied, because we need to be able to read and
37+
// write to a socket.
38+
if err := syncParentReady(l.pipe); err != nil {
39+
return errors.Wrap(err, "sync ready")
40+
}
41+
+ if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil {
42+
+ return errors.Wrap(err, "apply apparmor profile")
43+
+ }
44+
+ if l.config.NoNewPrivileges {
45+
+ if err := unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
46+
+ return errors.Wrap(err, "set nonewprivileges")
47+
+ }
48+
+ }
49+
+
50+
if err := selinux.SetExecLabel(l.config.ProcessLabel); err != nil {
51+
return errors.Wrap(err, "set process label")
52+
}
53+
--
54+
2.25.1
55+

docs/build.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,16 @@ lxc file pull test-build/root/microk8s/microk8s_v1.9.6_amd64.snap .
8383
After copying it, you can install it with:
8484

8585
```shell
86-
snap install microk8s_*_amd64.snap --classic --dangerous
86+
sudo snap install microk8s_latest_amd64.snap --dangerous
8787
```
8888

89+
Finally, you need to connect the interfaces. To this end you can use the `connect-all-interfaces.sh` under the `tests` directory:
90+
91+
```shell
92+
sudo tests/connect-all-interfaces.sh
93+
```
94+
95+
8996
## Assembling the Calico CNI manifest
9097

9198
The calico CNI manifest can be found under `upgrade-scripts/000-switch-to-calico/resources/calico.yaml`.

microk8s-resources/actions/common/utils.sh

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ exit_if_no_permissions() {
44
# test if we can access the default kubeconfig
55
if [ ! -r $SNAP_DATA/credentials/client.config ]; then
66
echo "Insufficient permissions to access MicroK8s." >&2
7-
echo "You can either try again with sudo or add the user $USER to the 'microk8s' group:" >&2
7+
echo "You can either try again with sudo or add the user $USER to the 'snap_microk8s' group:" >&2
88
echo "" >&2
9-
echo " sudo usermod -a -G microk8s $USER" >&2
9+
echo " sudo usermod -a -G snap_microk8s $USER" >&2
1010
echo " sudo chown -f -R $USER ~/.kube" >&2
1111
echo "" >&2
12-
echo "After this, reload the user groups either via a reboot or by running 'newgrp microk8s'." >&2
12+
echo "After this, reload the user groups either via a reboot or by running 'newgrp snap_microk8s'." >&2
1313
exit 1
1414
fi
1515
}
@@ -75,7 +75,7 @@ run_with_sudo() {
7575
then
7676
shift
7777
fi
78-
eval "$@"
78+
"$@"
7979
else
8080
if [ -n "${LD_LIBRARY_PATH-}" ]
8181
then
@@ -123,7 +123,7 @@ refresh_opt_in_local_config() {
123123
if $(grep -qE "^$opt=" $config_file); then
124124
run_with_sudo "$SNAP/bin/sed" -i "s@^$opt=.*@$replace_line@" $config_file
125125
else
126-
run_with_sudo "$SNAP/bin/sed" -i "$ a $replace_line" "$config_file"
126+
run_with_sudo "$SNAP/bin/sed" -i "1i$replace_line" "$config_file"
127127
fi
128128
}
129129

@@ -680,9 +680,9 @@ get_container_shim_pids() {
680680
}
681681

682682
kill_all_container_shims() {
683-
run_with_sudo systemctl kill snap.microk8s.daemon-kubelite.service --signal=SIGKILL &>/dev/null || true
684-
run_with_sudo systemctl kill snap.microk8s.daemon-kubelet.service --signal=SIGKILL &>/dev/null || true
685-
run_with_sudo systemctl kill snap.microk8s.daemon-containerd.service --signal=SIGKILL &>/dev/null || true
683+
run_with_sudo systemctl kill snap.microk8s.daemon-kubelite.service --signal=SIGKILL &>/dev/null || true
684+
run_with_sudo systemctl kill snap.microk8s.daemon-kubelet.service --signal=SIGKILL &>/dev/null || true
685+
run_with_sudo systemctl kill snap.microk8s.daemon-containerd.service --signal=SIGKILL &>/dev/null || true
686686
}
687687

688688
is_first_boot() {
@@ -829,9 +829,18 @@ fetch_as() {
829829

830830
############################# Strict functions ######################################
831831

832+
log_init () {
833+
echo `date +"[%m-%d %H:%M:%S]" start logging` > $SNAP_COMMON/var/log/microk8s.log
834+
}
835+
836+
log () {
837+
echo -n `date +"[%m-%d %H:%M:%S]"` >> $SNAP_COMMON/var/log/microk8s.log
838+
echo ": $@" >> $SNAP_COMMON/var/log/microk8s.log
839+
}
840+
832841
is_strict() {
833842
# Return 0 if we are in strict mode
834-
if cat $SNAP/meta/snap.yaml | grep confinement | grep strict
843+
if cat $SNAP/meta/snap.yaml | grep confinement | grep -q strict
835844
then
836845
return 0
837846
else
@@ -843,8 +852,8 @@ check_snap_interfaces() {
843852
# Check whether all of the required interfaces are connected before proceeding.
844853
# This is to address https://forum.snapcraft.io/t/mimic-sequence-of-hook-calls-with-auto-connected-interfaces/19618
845854
declare -ra interfaces=(
855+
"account-control"
846856
"docker-privileged"
847-
"docker-support"
848857
"dot-kube"
849858
"dot-config-helm"
850859
"firewall-control"
@@ -867,6 +876,7 @@ check_snap_interfaces() {
867876
"process-control"
868877
"system-observe"
869878
)
879+
870880
declare -a missing=()
871881

872882
for interface in ${interfaces[@]}
@@ -881,11 +891,34 @@ check_snap_interfaces() {
881891
then
882892
snapctl set-health blocked "You must connect ${missing[*]} before proceeding"
883893
exit 0
884-
else
885-
if [ $1 -gt 0 ]
886-
then
887-
snapctl start --enable ${SNAP_NAME}
888-
snapctl set-health okay
889-
fi
890894
fi
891895
}
896+
897+
enable_snap() {
898+
snapctl start --enable ${SNAP_NAME}
899+
snapctl set-health okay
900+
}
901+
902+
exit_if_not_root() {
903+
# test if we run with sudo
904+
if [ "$EUID" -ne 0 ]
905+
then echo "Elevated permissions are needed for this command. Please use sudo."
906+
exit 1
907+
fi
908+
}
909+
910+
is_first_boot_on_strict() {
911+
# Return 0 if this is the first start after the host booted.
912+
SENTINEL="/tmp/.containerd-first-book-check"
913+
# We rely on the fact that /tmp is cleared at every boot to determine if
914+
# this is the first call after boot: if the sentinel file exists, then it
915+
# means that no reboot occurred since last check; otherwise, return success
916+
# and create the sentinel file for the future check.
917+
if [ -f "$SENTINEL" ]
918+
then
919+
return 1
920+
else
921+
touch "$SENTINEL"
922+
return 0
923+
fi
924+
}

0 commit comments

Comments
 (0)