diff --git a/Dockerfile.in b/Dockerfile.in index 5c2528b..e4bc7b5 100644 --- a/Dockerfile.in +++ b/Dockerfile.in @@ -24,8 +24,8 @@ RUN apk update --no-cache && apk add \ git \ openssh-client -# Set $HOME so git can create things like .gitconfig -ENV HOME /tmp +RUN echo "git-sync:x:65533:65533::/tmp:/sbin/nologin" >> /etc/passwd -USER nobody:nobody +WORKDIR /tmp +USER git-sync:nobody ENTRYPOINT ["/{ARG_BIN}"] diff --git a/cmd/git-sync/main.go b/cmd/git-sync/main.go index eb148df..7a167c9 100644 --- a/cmd/git-sync/main.go +++ b/cmd/git-sync/main.go @@ -641,15 +641,11 @@ func setupGitSSH(setupKnownHosts bool) error { var pathToSSHSecret = *flSSHKeyFile var pathToSSHKnownHosts = *flSSHKnownHostsFile - fileInfo, err := os.Stat(pathToSSHSecret) + _, err := os.Stat(pathToSSHSecret) if err != nil { return fmt.Errorf("error: could not find SSH key Secret: %v", err) } - if fileInfo.Mode() != 0400 { - return fmt.Errorf("Permissions %s for SSH key are too open. It is recommended to mount secret volume with `defaultMode: 256` (decimal number for octal 0400).", fileInfo.Mode()) - } - if setupKnownHosts { _, err := os.Stat(pathToSSHKnownHosts) if err != nil { diff --git a/docs/ssh.md b/docs/ssh.md index 3d79ab8..907c445 100644 --- a/docs/ssh.md +++ b/docs/ssh.md @@ -3,24 +3,34 @@ Git-sync supports using the SSH protocol for pulling git content. ## Step 1: Create Secret -Create a Secret to store your SSH private key, with the Secret keyed as "ssh". This can be done one of two ways: + +Create a Secret to store your SSH private key, with the Secret keyed as "ssh". +This can be done one of two ways: ***Method 1:*** + Obtain the host keys for your git server: ``` ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts ``` -Use the ``kubectl create secret`` command and point to the file on your filesystem that stores the key. Ensure that the file is mapped to "ssh" as shown (the file can be located anywhere). +Use the `kubectl create secret` command and point to the file on your +filesystem that stores the key. Ensure that the file is mapped to "ssh" as +shown (the file can be located anywhere). + ``` -kubectl create secret generic git-creds --from-file=ssh=$HOME/.ssh/id_rsa --from-file=known_hosts=/tmp/known_hosts +kubectl create secret generic git-creds \ + --from-file=ssh=$HOME/.ssh/id_rsa \ + --from-file=known_hosts=/tmp/known_hosts ``` ***Method 2:*** -Write a config file for a Secret that holds your SSH private key, with the key (pasted in base64 encoded plaintext) mapped to the "ssh" field. +Write a config file for a Secret that holds your SSH private key, with the key +(pasted in base64 encoded plaintext) mapped to the "ssh" field. + ``` { "kind": "Secret", @@ -35,55 +45,107 @@ Write a config file for a Secret that holds your SSH private key, with the key ( } ``` -Create the Secret using ``kubectl create -f``. +Create the Secret using `kubectl create -f`. + ``` kubectl create -f /path/to/secret-config.json ``` -Invoke the `git-sync` binary with the `-ssh-known-hosts` parameter to enforce `known_hosts` checking. This will be enabled by default in a future release. +## Step 2: Configure Pod/Deployment volume -## Step 2: Configure Pod/Deployment Volume +In your Pod or Deployment configuration, specify a volume for mounting the +Secret. Ensure that secretName matches the name you used when creating the +Secret (e.g. "git-creds" used in both above examples). -In your Pod or Deployment configuration, specify a Volume for mounting the Secret. Ensure that secretName matches the name you used when creating the Secret (e.g. "git-creds" used in both above examples). ``` -volumes: [ - { - "name": "git-secret", - "secret": { - "secretName": "git-creds", - "defaultMode": 256 - } - }, - ... -], + # ... + volumes: + - name: git-secret + secret: + secretName: git-creds + defaultMode: 288 # 0440 + # ... ``` ## Step 3: Configure git-sync container -In your git-sync container configuration, mount the Secret Volume at "/etc/git-secret". Ensure that the environment variable GIT_SYNC_REPO is set to use a URL with the SSH protocol, and set GIT_SYNC_SSH to true. +In your git-sync container configuration, mount the Secret volume at +"/etc/git-secret". Ensure that the `-repo` flag (or the GIT_SYNC_REPO +environment variable) is set to use the SSH protocol (e.g. +git@github.com/foo/bar) , and set the `-ssh` flags (or set GIT_SYNC_SSH to +"true"). You will also need to set your container's `securityContext` to run +as user ID "65535" which is created for running git-syn as non-root. ``` -{ - name: "git-sync", - ... - env: [ - { - name: "GIT_SYNC_REPO", - value: "git@github.com:kubernetes/kubernetes.git", - }, { - name: "GIT_SYNC_SSH", - value: "true", - }, - ... - ] - volumeMounts: [ - { - "name": "git-secret", - "mountPath": "/etc/git-secret" - }, - ... - ], -} + # ... + containers: + - name: git-sync + image: k8s.gcr.io/git-sync:v9.3.76 + args: + - "-ssh" + - "-repo=git@github.com:foo/bar" + - "-dest=bar" + - "-branch=master" + volumeMounts: + - name: git-secret + mountPath: /etc/git-secret + securityContext: + runAsUser: 65533 # git-sync user + # ... ``` -**Note:** Kubernetes mounts the Secret with permissions 0444 by default (not restrictive enough to be used as an SSH key), so make sure you use secret volume with `defaultMode: 256` (decimal number for octal 0400). +Lastly, you need to tell your Pod to run with the git-sync FS group. Note +that this is a Pod-wide setting, unlike the container `securityContext` above. + +``` + # ... + securityContext: + fsGroup: 65533 # to make SSH key readable + # ... +``` + +**Note:** Kubernetes mounts the Secret with permissions 0444 by default (not +restrictive enough to be used as an SSH key), so make sure you set the +`defaultMode`. + +## Full example + +In case the above YAML snippets are confusing (because whitespace matters in +YAML), here is a full example: + +``` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: git-sync +spec: + selector: + matchLabels: + demo: git-sync + template: + metadata: + labels: + demo: git-sync + spec: + volumes: + - name: git-secret + secret: + secretName: git-creds + defaultMode: 288 # = mode 0440 + containers: + - name: git-sync + image: k8s.gcr.io/git-sync:v3.1.1 + args: + - "-ssh" + - "-repo=git@github.com:torvalds/linux" + - "-dest=linux" + - "-branch=master" + - "-depth=1" + securityContext: + runAsUser: 65533 # git-sync user + volumeMounts: + - name: git-secret + mountPath: /etc/git-secret + securityContext: + fsGroup: 65533 # to make SSH key readable +```