Skip to content

Commit 7bb3262

Browse files
authored
Merge pull request #144 from thockin/fix-ssh
Fix SSH
2 parents c1edeed + 51f19b8 commit 7bb3262

File tree

3 files changed

+107
-49
lines changed

3 files changed

+107
-49
lines changed

Dockerfile.in

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ RUN apk update --no-cache && apk add \
2424
git \
2525
openssh-client
2626

27-
# Set $HOME so git can create things like .gitconfig
28-
ENV HOME /tmp
27+
RUN echo "git-sync:x:65533:65533::/tmp:/sbin/nologin" >> /etc/passwd
2928

30-
USER nobody:nobody
29+
WORKDIR /tmp
30+
USER git-sync:nobody
3131
ENTRYPOINT ["/{ARG_BIN}"]

cmd/git-sync/main.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -641,15 +641,11 @@ func setupGitSSH(setupKnownHosts bool) error {
641641
var pathToSSHSecret = *flSSHKeyFile
642642
var pathToSSHKnownHosts = *flSSHKnownHostsFile
643643

644-
fileInfo, err := os.Stat(pathToSSHSecret)
644+
_, err := os.Stat(pathToSSHSecret)
645645
if err != nil {
646646
return fmt.Errorf("error: could not find SSH key Secret: %v", err)
647647
}
648648

649-
if fileInfo.Mode() != 0400 {
650-
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())
651-
}
652-
653649
if setupKnownHosts {
654650
_, err := os.Stat(pathToSSHKnownHosts)
655651
if err != nil {

docs/ssh.md

Lines changed: 103 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,34 @@
33
Git-sync supports using the SSH protocol for pulling git content.
44

55
## Step 1: Create Secret
6-
Create a Secret to store your SSH private key, with the Secret keyed as "ssh". This can be done one of two ways:
6+
7+
Create a Secret to store your SSH private key, with the Secret keyed as "ssh".
8+
This can be done one of two ways:
79

810
***Method 1:***
11+
912
Obtain the host keys for your git server:
1013

1114
```
1215
ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts
1316
```
1417

15-
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).
18+
Use the `kubectl create secret` command and point to the file on your
19+
filesystem that stores the key. Ensure that the file is mapped to "ssh" as
20+
shown (the file can be located anywhere).
21+
1622

1723
```
18-
kubectl create secret generic git-creds --from-file=ssh=$HOME/.ssh/id_rsa --from-file=known_hosts=/tmp/known_hosts
24+
kubectl create secret generic git-creds \
25+
--from-file=ssh=$HOME/.ssh/id_rsa \
26+
--from-file=known_hosts=/tmp/known_hosts
1927
```
2028

2129
***Method 2:***
2230

23-
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.
31+
Write a config file for a Secret that holds your SSH private key, with the key
32+
(pasted in base64 encoded plaintext) mapped to the "ssh" field.
33+
2434
```
2535
{
2636
"kind": "Secret",
@@ -35,55 +45,107 @@ Write a config file for a Secret that holds your SSH private key, with the key (
3545
}
3646
```
3747

38-
Create the Secret using ``kubectl create -f``.
48+
Create the Secret using `kubectl create -f`.
49+
3950
```
4051
kubectl create -f /path/to/secret-config.json
4152
```
4253

43-
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.
54+
## Step 2: Configure Pod/Deployment volume
4455

45-
## Step 2: Configure Pod/Deployment Volume
56+
In your Pod or Deployment configuration, specify a volume for mounting the
57+
Secret. Ensure that secretName matches the name you used when creating the
58+
Secret (e.g. "git-creds" used in both above examples).
4659

47-
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).
4860
```
49-
volumes: [
50-
{
51-
"name": "git-secret",
52-
"secret": {
53-
"secretName": "git-creds",
54-
"defaultMode": 256
55-
}
56-
},
57-
...
58-
],
61+
# ...
62+
volumes:
63+
- name: git-secret
64+
secret:
65+
secretName: git-creds
66+
defaultMode: 288 # 0440
67+
# ...
5968
```
6069

6170
## Step 3: Configure git-sync container
6271

63-
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.
72+
In your git-sync container configuration, mount the Secret volume at
73+
"/etc/git-secret". Ensure that the `-repo` flag (or the GIT_SYNC_REPO
74+
environment variable) is set to use the SSH protocol (e.g.
75+
[email protected]/foo/bar) , and set the `-ssh` flags (or set GIT_SYNC_SSH to
76+
"true"). You will also need to set your container's `securityContext` to run
77+
as user ID "65535" which is created for running git-syn as non-root.
6478

6579
```
66-
{
67-
name: "git-sync",
68-
...
69-
env: [
70-
{
71-
name: "GIT_SYNC_REPO",
72-
value: "[email protected]:kubernetes/kubernetes.git",
73-
}, {
74-
name: "GIT_SYNC_SSH",
75-
value: "true",
76-
},
77-
...
78-
]
79-
volumeMounts: [
80-
{
81-
"name": "git-secret",
82-
"mountPath": "/etc/git-secret"
83-
},
84-
...
85-
],
86-
}
80+
# ...
81+
containers:
82+
- name: git-sync
83+
image: k8s.gcr.io/git-sync:v9.3.76
84+
args:
85+
- "-ssh"
86+
- "[email protected]:foo/bar"
87+
- "-dest=bar"
88+
- "-branch=master"
89+
volumeMounts:
90+
- name: git-secret
91+
mountPath: /etc/git-secret
92+
securityContext:
93+
runAsUser: 65533 # git-sync user
94+
# ...
95+
```
96+
97+
Lastly, you need to tell your Pod to run with the git-sync FS group. Note
98+
that this is a Pod-wide setting, unlike the container `securityContext` above.
99+
87100
```
101+
# ...
102+
securityContext:
103+
fsGroup: 65533 # to make SSH key readable
104+
# ...
105+
```
106+
107+
**Note:** Kubernetes mounts the Secret with permissions 0444 by default (not
108+
restrictive enough to be used as an SSH key), so make sure you set the
109+
`defaultMode`.
88110

89-
**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).
111+
## Full example
112+
113+
In case the above YAML snippets are confusing (because whitespace matters in
114+
YAML), here is a full example:
115+
116+
```
117+
apiVersion: apps/v1
118+
kind: Deployment
119+
metadata:
120+
name: git-sync
121+
spec:
122+
selector:
123+
matchLabels:
124+
demo: git-sync
125+
template:
126+
metadata:
127+
labels:
128+
demo: git-sync
129+
spec:
130+
volumes:
131+
- name: git-secret
132+
secret:
133+
secretName: git-creds
134+
defaultMode: 288 # = mode 0440
135+
containers:
136+
- name: git-sync
137+
image: k8s.gcr.io/git-sync:v3.1.1
138+
args:
139+
- "-ssh"
140+
- "[email protected]:torvalds/linux"
141+
- "-dest=linux"
142+
- "-branch=master"
143+
- "-depth=1"
144+
securityContext:
145+
runAsUser: 65533 # git-sync user
146+
volumeMounts:
147+
- name: git-secret
148+
mountPath: /etc/git-secret
149+
securityContext:
150+
fsGroup: 65533 # to make SSH key readable
151+
```

0 commit comments

Comments
 (0)