From 73205cddac33a79dedd8aa34927245d6c549bc47 Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Fri, 24 Mar 2023 15:11:34 +0100 Subject: [PATCH 01/17] WIP: adhoc SSH debugging --- Earthfile | 1 + api/v1beta1/loadbalancer_types.go | 9 ++++ .../yawollet/loadbalancer_controller.go | 5 ++ image/install-alpine.yaml | 11 +++++ image/yawol-sudoers | 1 + internal/helper/yawollet.go | 46 +++++++++++++++++++ 6 files changed, 73 insertions(+) create mode 100644 image/yawol-sudoers diff --git a/Earthfile b/Earthfile index f3389ab8..e930cfb0 100644 --- a/Earthfile +++ b/Earthfile @@ -52,6 +52,7 @@ local: build-local: BUILD +local --CONTROLLER=yawol-controller BUILD +local --CONTROLLER=yawol-cloud-controller + BUILD +local --CONTROLLER=yawollet build-test: FROM +deps diff --git a/api/v1beta1/loadbalancer_types.go b/api/v1beta1/loadbalancer_types.go index d5724611..2ecd7c51 100644 --- a/api/v1beta1/loadbalancer_types.go +++ b/api/v1beta1/loadbalancer_types.go @@ -55,6 +55,15 @@ const ( ServiceAdditionalNetworks = "yawol.stackit.cloud/additionalNetworks" ) +// Annotation for settings in lb object +const ( + // LoadBalancerAdHocDebug enables adhoc debugging, all LoadBalancer Machines will enable SSH + LoadBalancerAdHocDebug = "yawol.stackit.cloud/adHocDebug" + // LoadBalancerAdHocDebugSSHKey defines the public ssh key for adhoc debugging + // All LoadBalancer Machines will add this public SSH key + LoadBalancerAdHocDebugSSHKey = "yawol.stackit.cloud/adHocDebugSSHKey" +) + // +kubebuilder:object:root=true // +kubebuilder:resource:shortName=lb // +kubebuilder:subresource:status diff --git a/controllers/yawollet/loadbalancer_controller.go b/controllers/yawollet/loadbalancer_controller.go index bb41ddd7..ec3c0898 100644 --- a/controllers/yawollet/loadbalancer_controller.go +++ b/controllers/yawollet/loadbalancer_controller.go @@ -55,6 +55,11 @@ func (r *LoadBalancerReconciler) Reconcile(ctx context.Context, req ctrl.Request return ctrl.Result{}, err } + // enable ad hoc debugging if configured + if err := helper.EnableAdHocDebugging(lb, r.Recorder, r.LoadbalancerMachineName); err != nil { + return ctrl.Result{}, kubernetes.SendErrorAsEvent(r.Recorder, fmt.Errorf("%w: unable to get current snapshot", err), lbm) + } + // current snapshot oldSnapshot, err := r.EnvoyCache.GetSnapshot("lb-id") if err != nil { diff --git a/image/install-alpine.yaml b/image/install-alpine.yaml index 2910ba9a..ccd35352 100644 --- a/image/install-alpine.yaml +++ b/image/install-alpine.yaml @@ -60,6 +60,14 @@ state: directory mode: '0755' + - name: add sudoers file for yawol + copy: + src: ./yawol-sudoers + dest: /etc/sudoers.d/yawol + owner: root + group: root + mode: 0644 + # envoy - name: Copy envoy in place copy: @@ -237,3 +245,6 @@ - name: more cleanup command: "cloud-init clean -l -s" + + - name: cleanup ssh-keys + command: "> /home/alpine/.ssh/authorized_keys" diff --git a/image/yawol-sudoers b/image/yawol-sudoers new file mode 100644 index 00000000..39e9e79d --- /dev/null +++ b/image/yawol-sudoers @@ -0,0 +1 @@ +yawol ALL = NOPASSWD: /sbin/rc-service sshd start diff --git a/internal/helper/yawollet.go b/internal/helper/yawollet.go index 3b93c923..f7ecd194 100644 --- a/internal/helper/yawollet.go +++ b/internal/helper/yawollet.go @@ -5,6 +5,8 @@ import ( "encoding/json" "fmt" "net" + "os" + "os/exec" "regexp" "strconv" "strings" @@ -781,3 +783,47 @@ func UpdateKeepalivedStatus( ConditionTrue, "StatsUpToDate", "Keepalived stat file is newer than 5 min") } + +// EnableAdHocDebugging enables ad-hoc debugging if enabled via annotations. +func EnableAdHocDebugging(lb *yawolv1beta1.LoadBalancer, recorder record.EventRecorder, lbmName string) error { + // skip if debugging is enabled anyway + if lb.Spec.DebugSettings.Enabled { + return nil + } + + enabled, _ := strconv.ParseBool(lb.Annotations[yawolv1beta1.LoadBalancerAdHocDebug]) + sshKey, sshKeySet := lb.Annotations[yawolv1beta1.LoadBalancerAdHocDebugSSHKey] + + // skip not all needed annotations are set or disabled + if !enabled || !sshKeySet { + return nil + } + + err := os.MkdirAll("/home/yawol/.ssh", 0755) + if err != nil { + return err + } + + f, err := os.OpenFile("/home/yawol/.ssh/authorized_keys", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600) + if err != nil { + return err + } + defer f.Close() + + if _, err := f.Write([]byte("\n" + sshKey + "\n")); err != nil { + return err + } + + if err := f.Close(); err != nil { + return err + } + + startSSH := exec.Command("sudo", "/sbin/rc-service", "sshd", "start") + if err = startSSH.Run(); err != nil { + return err + } + + recorder.Eventf(lb, corev1.EventTypeWarning, "AdHocDebuggingEnabled", "Successfully enabled ad-hoc debugging access to LoadBalancerMachine '%s'. Please make sure to disable debug access once you are finished and to roll all LoadBalancerMachines", lbmName) + + return nil +} From 4179a010d7b263b3f4b0d49ed2d86ca6275ecd34 Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Mon, 27 Mar 2023 10:53:14 +0200 Subject: [PATCH 02/17] add adhoc debug to sec group --- internal/helper/loadbalancer.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/internal/helper/loadbalancer.go b/internal/helper/loadbalancer.go index 394a50ea..93b716bd 100644 --- a/internal/helper/loadbalancer.go +++ b/internal/helper/loadbalancer.go @@ -272,7 +272,10 @@ func getSecGroupRulesForPorts(r record.EventRecorder, lb *yawolv1beta1.LoadBalan } func getSecGroupRulesForDebugSettings(r record.EventRecorder, lb *yawolv1beta1.LoadBalancer) []rules.SecGroupRule { - if !lb.Spec.DebugSettings.Enabled { + adHocDebug, _ := strconv.ParseBool(lb.Annotations[yawolv1beta1.LoadBalancerAdHocDebug]) + + if !lb.Spec.DebugSettings.Enabled && + !adHocDebug { return []rules.SecGroupRule{} } From 17281dddae81b809064960954fe05b317d25ae17 Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Mon, 27 Mar 2023 12:58:47 +0200 Subject: [PATCH 03/17] add envoylibs and promtail to get local in Earthfile --- Earthfile | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Earthfile b/Earthfile index e930cfb0..1f166cb3 100644 --- a/Earthfile +++ b/Earthfile @@ -63,7 +63,17 @@ build-test: get-envoy-local: FROM +envoy COPY +get-envoy/envoy /envoy - SAVE ARTIFACT /envoy AS LOCAL out/envoy + SAVE ARTIFACT /envoy AS LOCAL out/envoy/envoy + +get-envoy-libs-local: + FROM +envoy + COPY +get-envoy/envoylibs /envoylibs + SAVE ARTIFACT /envoylibs AS LOCAL out/envoy/lib + +get-promtail-local: + FROM +promtail + COPY +promtail/promtail /promtail + SAVE ARTIFACT /promtail AS LOCAL out/promtail get-envoy: FROM +envoy From 9e1a5f329320180a37da2ce4ee79c9485a3440bb Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Mon, 27 Mar 2023 13:00:28 +0200 Subject: [PATCH 04/17] fix lint --- internal/helper/yawollet.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/internal/helper/yawollet.go b/internal/helper/yawollet.go index f7ecd194..009e9388 100644 --- a/internal/helper/yawollet.go +++ b/internal/helper/yawollet.go @@ -810,7 +810,7 @@ func EnableAdHocDebugging(lb *yawolv1beta1.LoadBalancer, recorder record.EventRe } defer f.Close() - if _, err := f.Write([]byte("\n" + sshKey + "\n")); err != nil { + if _, err := f.WriteString("\n" + sshKey + "\n"); err != nil { return err } @@ -819,11 +819,14 @@ func EnableAdHocDebugging(lb *yawolv1beta1.LoadBalancer, recorder record.EventRe } startSSH := exec.Command("sudo", "/sbin/rc-service", "sshd", "start") - if err = startSSH.Run(); err != nil { + if err := startSSH.Run(); err != nil { return err } - recorder.Eventf(lb, corev1.EventTypeWarning, "AdHocDebuggingEnabled", "Successfully enabled ad-hoc debugging access to LoadBalancerMachine '%s'. Please make sure to disable debug access once you are finished and to roll all LoadBalancerMachines", lbmName) + recorder.Eventf(lb, corev1.EventTypeWarning, + "AdHocDebuggingEnabled", + "Successfully enabled ad-hoc debugging access to LoadBalancerMachine '%s'. "+ + "Please make sure to disable debug access once you are finished and to roll all LoadBalancerMachines", lbmName) return nil } From 94463b5d8319663bd282187147b0688ffef321ee Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Mon, 27 Mar 2023 13:01:32 +0200 Subject: [PATCH 05/17] configure sshd, unlock yawol user, cleanup ssh-keys after build --- image/install-alpine.yaml | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/image/install-alpine.yaml b/image/install-alpine.yaml index ccd35352..d75d015a 100644 --- a/image/install-alpine.yaml +++ b/image/install-alpine.yaml @@ -23,6 +23,25 @@ search_string: 'slaac hwaddr' line: 'slaac hwaddr' + # sshd config + - name: disable root login + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^PermitRootLogin.*$ + line: 'PermitRootLogin no' + + - name: disable login without password + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^PermitEmptyPasswords.*$ + line: 'PermitEmptyPasswords no' + + - name: disable login password login + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^PasswordAuthentication.*$ + line: 'PasswordAuthentication no' + # keepalived - name: install keepalived command: "apk add keepalived" @@ -53,6 +72,7 @@ user: name: "yawol" shell: /bin/ash + password: '*' - name: Create a directory for yawol file: @@ -247,4 +267,7 @@ command: "cloud-init clean -l -s" - name: cleanup ssh-keys - command: "> /home/alpine/.ssh/authorized_keys" + lineinfile: + path: /home/alpine/.ssh/authorized_keys + state: absent + regexp: '.*' From 70a64f1183ab5bafed69344ba7e40f3c10786a69 Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Mon, 27 Mar 2023 13:01:51 +0200 Subject: [PATCH 06/17] add ad hoc debugging to README --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index 95af2326..df21471b 100644 --- a/README.md +++ b/README.md @@ -286,6 +286,31 @@ kubectl create deploy --image nginx --port 80 nginx kubectl expose deployment nginx --port 80 --type LoadBalancer ``` +## Troubleshooting + +There are currently 2 debug options to access the `LoadBalancerMachine` VM via SSH: + +### Debug settings within the `LoadBalancer` `.spec.debugSettings` +This will add the SSH key via OpenStack KeyPair. A change will recreate the `LoadBalancerMachines`, because OpenStack +KeyPairs are only possible while VM creation. + +This can be also enabled with the service annotations: `yawol.stackit.cloud/debug` and `yawol.stackit.cloud/debugsshkey` + +> You can login with the user: `alpine` + +### Ad hoc debugging +To troubleshoot a running `LoadBalancerMachine` we added a function into the `yawollet` to be able to add a SSH key +and enable/start sshd on the fly. + +This can only be enabled with annotations on the `LoadBalancer`: `yawol.stackit.cloud/adHocDebug` and `yawol.stackit.cloud/adHocDebugSSHKey` + +This will not recreate the `LoadBalancerMachine`. Be aware that the `yawol.stackit.cloud/adHocDebugSSHKey` has to contain the complete +SSH public key. + +> You can login with the user: `yawol` + +> After you are done please remove the VMs, because yawol will **not** disable SSH again. + ## Development See the [development guide](docs/development.md). From ab3425e1f31b881a1a6347f0a85b1db334c32b94 Mon Sep 17 00:00:00 2001 From: Maximilian Geberl <48486938+dergeberl@users.noreply.github.com> Date: Mon, 27 Mar 2023 13:48:41 +0200 Subject: [PATCH 07/17] fix typo Co-authored-by: Felix Breuer Signed-off-by: Maximilian Geberl <48486938+dergeberl@users.noreply.github.com> --- image/install-alpine.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/install-alpine.yaml b/image/install-alpine.yaml index d75d015a..63b99457 100644 --- a/image/install-alpine.yaml +++ b/image/install-alpine.yaml @@ -36,7 +36,7 @@ regexp: ^PermitEmptyPasswords.*$ line: 'PermitEmptyPasswords no' - - name: disable login password login + - name: disable password login ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: ^PasswordAuthentication.*$ From c39bb1589d01b832984f282a869c7995935bcc8e Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Mon, 27 Mar 2023 14:26:24 +0200 Subject: [PATCH 08/17] add check if ssh-key is already in authorized_keys --- internal/helper/yawollet.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/internal/helper/yawollet.go b/internal/helper/yawollet.go index 009e9388..3776367b 100644 --- a/internal/helper/yawollet.go +++ b/internal/helper/yawollet.go @@ -1,6 +1,7 @@ package helper import ( + "bufio" "context" "encoding/json" "fmt" @@ -810,8 +811,18 @@ func EnableAdHocDebugging(lb *yawolv1beta1.LoadBalancer, recorder record.EventRe } defer f.Close() - if _, err := f.WriteString("\n" + sshKey + "\n"); err != nil { - return err + scanner := bufio.NewScanner(f) + var found bool + for scanner.Scan() { + if strings.Contains(scanner.Text(), sshKey) { + found = true + break + } + } + if !found { + if _, err := f.WriteString("\n" + sshKey + "\n"); err != nil { + return err + } } if err := f.Close(); err != nil { From 6714efe0a50b0069c774704ea63d53dfeb1c4743 Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Mon, 27 Mar 2023 15:06:55 +0200 Subject: [PATCH 09/17] move event to lbm --- controllers/yawollet/loadbalancer_controller.go | 2 +- internal/helper/yawollet.go | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/controllers/yawollet/loadbalancer_controller.go b/controllers/yawollet/loadbalancer_controller.go index ec3c0898..5c8ed128 100644 --- a/controllers/yawollet/loadbalancer_controller.go +++ b/controllers/yawollet/loadbalancer_controller.go @@ -56,7 +56,7 @@ func (r *LoadBalancerReconciler) Reconcile(ctx context.Context, req ctrl.Request } // enable ad hoc debugging if configured - if err := helper.EnableAdHocDebugging(lb, r.Recorder, r.LoadbalancerMachineName); err != nil { + if err := helper.EnableAdHocDebugging(lb, lbm, r.Recorder, r.LoadbalancerMachineName); err != nil { return ctrl.Result{}, kubernetes.SendErrorAsEvent(r.Recorder, fmt.Errorf("%w: unable to get current snapshot", err), lbm) } diff --git a/internal/helper/yawollet.go b/internal/helper/yawollet.go index 3776367b..a9579105 100644 --- a/internal/helper/yawollet.go +++ b/internal/helper/yawollet.go @@ -786,7 +786,7 @@ func UpdateKeepalivedStatus( } // EnableAdHocDebugging enables ad-hoc debugging if enabled via annotations. -func EnableAdHocDebugging(lb *yawolv1beta1.LoadBalancer, recorder record.EventRecorder, lbmName string) error { +func EnableAdHocDebugging(lb *yawolv1beta1.LoadBalancer, lbm *yawolv1beta1.LoadBalancerMachine, recorder record.EventRecorder, lbmName string) error { // skip if debugging is enabled anyway if lb.Spec.DebugSettings.Enabled { return nil @@ -834,10 +834,9 @@ func EnableAdHocDebugging(lb *yawolv1beta1.LoadBalancer, recorder record.EventRe return err } - recorder.Eventf(lb, corev1.EventTypeWarning, + recorder.Eventf(lbm, corev1.EventTypeWarning, "AdHocDebuggingEnabled", "Successfully enabled ad-hoc debugging access to LoadBalancerMachine '%s'. "+ "Please make sure to disable debug access once you are finished and to roll all LoadBalancerMachines", lbmName) - return nil } From d6df2a3ba0aa291da7aa4b7f4ec8105f35672fef Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Mon, 27 Mar 2023 15:41:54 +0200 Subject: [PATCH 10/17] fix lint --- internal/helper/yawollet.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/helper/yawollet.go b/internal/helper/yawollet.go index a9579105..db93374a 100644 --- a/internal/helper/yawollet.go +++ b/internal/helper/yawollet.go @@ -786,7 +786,12 @@ func UpdateKeepalivedStatus( } // EnableAdHocDebugging enables ad-hoc debugging if enabled via annotations. -func EnableAdHocDebugging(lb *yawolv1beta1.LoadBalancer, lbm *yawolv1beta1.LoadBalancerMachine, recorder record.EventRecorder, lbmName string) error { +func EnableAdHocDebugging( + lb *yawolv1beta1.LoadBalancer, + lbm *yawolv1beta1.LoadBalancerMachine, + recorder record.EventRecorder, + lbmName string, +) error { // skip if debugging is enabled anyway if lb.Spec.DebugSettings.Enabled { return nil From 526c59dffd1f0425769072afc91ea0153245b910 Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Wed, 29 Mar 2023 10:16:36 +0200 Subject: [PATCH 11/17] update docs --- README.md | 25 --------------------- docs/development.md | 54 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index df21471b..95af2326 100644 --- a/README.md +++ b/README.md @@ -286,31 +286,6 @@ kubectl create deploy --image nginx --port 80 nginx kubectl expose deployment nginx --port 80 --type LoadBalancer ``` -## Troubleshooting - -There are currently 2 debug options to access the `LoadBalancerMachine` VM via SSH: - -### Debug settings within the `LoadBalancer` `.spec.debugSettings` -This will add the SSH key via OpenStack KeyPair. A change will recreate the `LoadBalancerMachines`, because OpenStack -KeyPairs are only possible while VM creation. - -This can be also enabled with the service annotations: `yawol.stackit.cloud/debug` and `yawol.stackit.cloud/debugsshkey` - -> You can login with the user: `alpine` - -### Ad hoc debugging -To troubleshoot a running `LoadBalancerMachine` we added a function into the `yawollet` to be able to add a SSH key -and enable/start sshd on the fly. - -This can only be enabled with annotations on the `LoadBalancer`: `yawol.stackit.cloud/adHocDebug` and `yawol.stackit.cloud/adHocDebugSSHKey` - -This will not recreate the `LoadBalancerMachine`. Be aware that the `yawol.stackit.cloud/adHocDebugSSHKey` has to contain the complete -SSH public key. - -> You can login with the user: `yawol` - -> After you are done please remove the VMs, because yawol will **not** disable SSH again. - ## Development See the [development guide](docs/development.md). diff --git a/docs/development.md b/docs/development.md index e86f12ed..0570c6bf 100644 --- a/docs/development.md +++ b/docs/development.md @@ -176,15 +176,22 @@ TCP testing using the admin port of Envoy: 1. Open http://localhost:8085 in your browser 2. You should get forwarded to the admin port of Envoy which is listening to localhost:9000 -## Live-Debugging yawollet +## Troubleshooting - SSH access to yawol VM + +There are currently 2 debug options to access the `LoadBalancerMachine` VM via SSH: + +### Debug settings within the `LoadBalancer` `.spec.debugSettings` +This will add the SSH key via OpenStack KeyPair. A change will recreate the `LoadBalancerMachines`, because OpenStack +KeyPairs are only possible while VM creation. 1. Upload ssh key-pair to OpenStack - ```bash - openstack keypair create # create new keypair - # or - openstack keypair create --public-key # add existing pubkey - ``` +```bash +openstack keypair create # create new keypair +# or +openstack keypair create --public-key # add existing pubkey +``` + 2. Add the following to `LoadBalancer`: @@ -197,4 +204,37 @@ TCP testing using the admin port of Envoy: ... ``` -3. SSH into the VM with username `alpine` and `externalIP` from `LoadBalancer` +This can be also enabled with the service annotations: `yawol.stackit.cloud/debug` and `yawol.stackit.cloud/debugsshkey` + +> You can login with the user: `alpine` + +### Ad hoc debugging +To troubleshoot a running `LoadBalancerMachine` we added a function into the `yawollet` to be able to add a SSH key +and enable/start sshd on the fly. + +This can only be enabled with annotations on the `LoadBalancer`: `yawol.stackit.cloud/adHocDebug` and `yawol.stackit.cloud/adHocDebugSSHKey` + +This will not recreate the `LoadBalancerMachine`. Be aware that the `yawol.stackit.cloud/adHocDebugSSHKey` has to contain the complete +SSH public key. + +> You can login with the user: `yawoldebug` + +> After you are done please remove the VMs, because yawol will **not** disable SSH again. + + +## Image Build + +For the image build ansible is used. To develop on ansible you can run in locally. +Therefore, you need to get/build all needed binaries and change to the `image` directory: + +``` +earthly +get-envoy-local +earthly +get-envoy-libs-local +earthly +get-promtail-local +earthly +build-local +``` + +Now you can run ansible: +``` +ansible-playbook -i , --private-key=~/.ssh/ske-key --user alpine install-alpine.yaml +``` From fe048c487e1ffc4cba8ff6efb93b9a9360914641 Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Wed, 29 Mar 2023 10:16:59 +0200 Subject: [PATCH 12/17] add debug user --- image/install-alpine.yaml | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/image/install-alpine.yaml b/image/install-alpine.yaml index 63b99457..d3760d1a 100644 --- a/image/install-alpine.yaml +++ b/image/install-alpine.yaml @@ -1,6 +1,6 @@ --- - name: install dependencies and envoy to machine - hosts: default + hosts: all become: true tasks: # alpine updates @@ -67,12 +67,18 @@ group: root mode: 0755 + # create yawol group + - name: Creating yawol group + ansible.builtin.group: + name: yawol + state: present + # yawol user - name: Creating yawol user user: name: "yawol" + group: "yawol" shell: /bin/ash - password: '*' - name: Create a directory for yawol file: @@ -88,6 +94,22 @@ group: root mode: 0644 + # yawoldebug user + - name: Creating yawol user + user: + name: "yawoldebug" + group: "yawol" + shell: /bin/ash + password: "*" + + - name: Create a .ssh directory for yawoldebug user + file: + path: /home/yawoldebug/.ssh + owner: "yawoldebug" + group: "yawol" + state: directory + mode: '0770' + # envoy - name: Copy envoy in place copy: @@ -271,3 +293,4 @@ path: /home/alpine/.ssh/authorized_keys state: absent regexp: '.*' + From 17f684ab290f11fa5d2af3b6e257025b760b600f Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Wed, 29 Mar 2023 10:17:33 +0200 Subject: [PATCH 13/17] replace authorized_keys instead of append --- internal/helper/yawollet.go | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/internal/helper/yawollet.go b/internal/helper/yawollet.go index db93374a..f2086c42 100644 --- a/internal/helper/yawollet.go +++ b/internal/helper/yawollet.go @@ -1,7 +1,6 @@ package helper import ( - "bufio" "context" "encoding/json" "fmt" @@ -810,24 +809,14 @@ func EnableAdHocDebugging( return err } - f, err := os.OpenFile("/home/yawol/.ssh/authorized_keys", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600) + f, err := os.OpenFile("/home/yawoldebug/.ssh/authorized_keys", os.O_WRONLY|os.O_CREATE, 0660) if err != nil { return err } defer f.Close() - scanner := bufio.NewScanner(f) - var found bool - for scanner.Scan() { - if strings.Contains(scanner.Text(), sshKey) { - found = true - break - } - } - if !found { - if _, err := f.WriteString("\n" + sshKey + "\n"); err != nil { - return err - } + if _, err := f.WriteString("\n" + sshKey + "\n"); err != nil { + return err } if err := f.Close(); err != nil { From b7f2d5960bd07e8524822d3ef1fc29d240eaa3a8 Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Wed, 29 Mar 2023 14:38:48 +0200 Subject: [PATCH 14/17] use sudo for authorized_keys to get the correct file permissions --- image/install-alpine.yaml | 20 ++++++++++---------- image/yawol-sudoers | 1 + internal/helper/yawollet.go | 19 ++----------------- 3 files changed, 13 insertions(+), 27 deletions(-) diff --git a/image/install-alpine.yaml b/image/install-alpine.yaml index d3760d1a..c667cc20 100644 --- a/image/install-alpine.yaml +++ b/image/install-alpine.yaml @@ -67,17 +67,10 @@ group: root mode: 0755 - # create yawol group - - name: Creating yawol group - ansible.builtin.group: - name: yawol - state: present - # yawol user - name: Creating yawol user user: name: "yawol" - group: "yawol" shell: /bin/ash - name: Create a directory for yawol @@ -98,7 +91,8 @@ - name: Creating yawol user user: name: "yawoldebug" - group: "yawol" + groups: + - wheel shell: /bin/ash password: "*" @@ -106,9 +100,15 @@ file: path: /home/yawoldebug/.ssh owner: "yawoldebug" - group: "yawol" state: directory - mode: '0770' + mode: '0700' + + - name: Create a .ssh(authorized_keys file for yawoldebug user + file: + path: /home/yawoldebug/.ssh/authorized_keys + owner: "yawoldebug" + state: touch + mode: '0600' # envoy - name: Copy envoy in place diff --git a/image/yawol-sudoers b/image/yawol-sudoers index 39e9e79d..8df622c0 100644 --- a/image/yawol-sudoers +++ b/image/yawol-sudoers @@ -1 +1,2 @@ yawol ALL = NOPASSWD: /sbin/rc-service sshd start +yawol ALL = NOPASSWD: /usr/bin/tee /home/yawoldebug/.ssh/authorized_keys diff --git a/internal/helper/yawollet.go b/internal/helper/yawollet.go index f2086c42..073b71eb 100644 --- a/internal/helper/yawollet.go +++ b/internal/helper/yawollet.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "net" - "os" "os/exec" "regexp" "strconv" @@ -804,22 +803,8 @@ func EnableAdHocDebugging( return nil } - err := os.MkdirAll("/home/yawol/.ssh", 0755) - if err != nil { - return err - } - - f, err := os.OpenFile("/home/yawoldebug/.ssh/authorized_keys", os.O_WRONLY|os.O_CREATE, 0660) - if err != nil { - return err - } - defer f.Close() - - if _, err := f.WriteString("\n" + sshKey + "\n"); err != nil { - return err - } - - if err := f.Close(); err != nil { + addAuthorizedKeys := exec.Command("/bin/sh", "-c", "echo \"\n"+sshKey+"\n\" | sudo tee /home/yawoldebug/.ssh/authorized_keys") + if err := addAuthorizedKeys.Run(); err != nil { return err } From b745e4d65650d31438d40af1170d190fe49afd02 Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Wed, 29 Mar 2023 15:01:36 +0200 Subject: [PATCH 15/17] add yawoldebug user to sudoers --- image/install-alpine.yaml | 2 -- image/yawol-sudoers | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/image/install-alpine.yaml b/image/install-alpine.yaml index c667cc20..9f858278 100644 --- a/image/install-alpine.yaml +++ b/image/install-alpine.yaml @@ -91,8 +91,6 @@ - name: Creating yawol user user: name: "yawoldebug" - groups: - - wheel shell: /bin/ash password: "*" diff --git a/image/yawol-sudoers b/image/yawol-sudoers index 8df622c0..ed2e9a28 100644 --- a/image/yawol-sudoers +++ b/image/yawol-sudoers @@ -1,2 +1,4 @@ yawol ALL = NOPASSWD: /sbin/rc-service sshd start yawol ALL = NOPASSWD: /usr/bin/tee /home/yawoldebug/.ssh/authorized_keys + +yawoldebug ALL=(ALL) NOPASSWD:ALL From 464e366c24fc5c0db29e10215d6cece6f0501d4d Mon Sep 17 00:00:00 2001 From: Maximilian Geberl Date: Wed, 29 Mar 2023 15:19:29 +0200 Subject: [PATCH 16/17] add events and fix lint --- internal/helper/yawollet.go | 41 +++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/internal/helper/yawollet.go b/internal/helper/yawollet.go index 073b71eb..96124856 100644 --- a/internal/helper/yawollet.go +++ b/internal/helper/yawollet.go @@ -113,6 +113,11 @@ const ( const dnsName string = `^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9])).([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}.[a-zA-Z]{2,3})$` //nolint:lll // long regex var rxDNSName = regexp.MustCompile(dnsName) +// Const declaration for SSH pub key checking +const sshPublicKey = `^ssh-rsa\s+[A-Za-z0-9+/=]+$` + +var rxSSHPublicKey = regexp.MustCompile(sshPublicKey) + // CreateEnvoyConfig create a new envoy snapshot and checks if the new snapshot has changes func CreateEnvoyConfig( r record.EventRecorder, @@ -790,11 +795,6 @@ func EnableAdHocDebugging( recorder record.EventRecorder, lbmName string, ) error { - // skip if debugging is enabled anyway - if lb.Spec.DebugSettings.Enabled { - return nil - } - enabled, _ := strconv.ParseBool(lb.Annotations[yawolv1beta1.LoadBalancerAdHocDebug]) sshKey, sshKeySet := lb.Annotations[yawolv1beta1.LoadBalancerAdHocDebugSSHKey] @@ -803,14 +803,39 @@ func EnableAdHocDebugging( return nil } - addAuthorizedKeys := exec.Command("/bin/sh", "-c", "echo \"\n"+sshKey+"\n\" | sudo tee /home/yawoldebug/.ssh/authorized_keys") + // skip if debugging is enabled anyway + if lb.Spec.DebugSettings.Enabled { + recorder.Event(lbm, corev1.EventTypeWarning, + "AdHocDebuggingNotEnabled", + "Ad-hoc debugging will not be enabled because normal debug with is already enabled") + return nil + } + + if !rxSSHPublicKey.MatchString(sshKey) { + recorder.Event(lbm, corev1.EventTypeWarning, + "AdHocDebuggingNotEnabled", + "Ad-hoc debugging will not be enabled because ssh key is not valid") + return nil + } + + addAuthorizedKeys := exec.Command( //nolint: gosec // sshKey can only be a ssh public key checked by regex + "/bin/sh", + "-c", + "echo \"\n"+sshKey+"\n\" | sudo tee /home/yawoldebug/.ssh/authorized_keys", + ) if err := addAuthorizedKeys.Run(); err != nil { - return err + recorder.Eventf(lbm, corev1.EventTypeWarning, + "AdHocDebuggingNotEnabled", + "Ad-hoc debugging cant be enabled because authorized_keys cant be written: %v", err) + return nil // no error to be sure the loadbalancer still will be reconciled } startSSH := exec.Command("sudo", "/sbin/rc-service", "sshd", "start") if err := startSSH.Run(); err != nil { - return err + recorder.Eventf(lbm, corev1.EventTypeWarning, + "AdHocDebuggingNotEnabled", + "Ad-hoc debugging cant be enabled because ssh cant be started: %v", err) + return nil // no error to be sure the loadbalancer still will be reconciled } recorder.Eventf(lbm, corev1.EventTypeWarning, From 0a341ba03315f06557d0b939841b4727b86e2133 Mon Sep 17 00:00:00 2001 From: Maximilian Geberl <48486938+dergeberl@users.noreply.github.com> Date: Wed, 29 Mar 2023 16:15:16 +0200 Subject: [PATCH 17/17] Update image/install-alpine.yaml Co-authored-by: Felix Breuer Signed-off-by: Maximilian Geberl <48486938+dergeberl@users.noreply.github.com> --- image/install-alpine.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/install-alpine.yaml b/image/install-alpine.yaml index 9f858278..19b12882 100644 --- a/image/install-alpine.yaml +++ b/image/install-alpine.yaml @@ -101,7 +101,7 @@ state: directory mode: '0700' - - name: Create a .ssh(authorized_keys file for yawoldebug user + - name: Create a .ssh/authorized_keys file for yawoldebug user file: path: /home/yawoldebug/.ssh/authorized_keys owner: "yawoldebug"