Skip to content

Commit 6a7e23d

Browse files
authored
Sign all Images, also push to GHCR, closes #44 (#45)
* Update to Go 1.24.1 * Add Cosign for "testing" images * sign a multi-arch container image AND all referenced, discrete images, fixes #44 * additionally push images to GHCR * Gosec Action * Solve Gosec G115 * Push testing image to GHCR, sign GHCR images * Update Cosign to 2.4.3 in prod action, fix Gosec * Sign images for Docker registry and GHCR * update documentation --------- Co-authored-by: wollomatic <[email protected]>
1 parent 8f15c07 commit 6a7e23d

File tree

6 files changed

+85
-17
lines changed

6 files changed

+85
-17
lines changed

.github/workflows/docker-image-release.yaml

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,26 @@ jobs:
99
build:
1010

1111
runs-on: ubuntu-latest
12+
env:
13+
GO111MODULE: on
1214

1315
steps:
1416
- name: Checkout
1517
uses: actions/checkout@v4
1618

1719
- name: Run Gosec Security Scanner
1820
uses: securego/gosec@master
21+
with:
22+
args: ./...
1923

2024
- name: Extract tag name
2125
id: get_tag
2226
run: echo "::set-output name=VERSION::${GITHUB_REF#refs/tags/}"
2327

2428
- name: Install Cosign
25-
uses: sigstore/cosign-installer@v3.1.2
29+
uses: sigstore/cosign-installer@v3.8.1
2630
with:
27-
cosign-release: 'v2.2.0'
31+
cosign-release: 'v2.4.3'
2832

2933
- name: Set up Docker Buildx
3034
uses: docker/setup-buildx-action@v3
@@ -35,6 +39,13 @@ jobs:
3539
username: ${{ secrets.DOCKERHUB_USERNAME }}
3640
password: ${{ secrets.DOCKERHUB_TOKEN }}
3741

42+
- name: Login to GitHub Container Registry
43+
uses: docker/login-action@v3
44+
with:
45+
registry: ghcr.io
46+
username: ${{ github.actor }}
47+
password: ${{ secrets.GITHUB_TOKEN }}
48+
3849
- name: Build and push Docker image
3950
uses: docker/build-push-action@v5
4051
id: build-and-push
@@ -43,10 +54,20 @@ jobs:
4354
platforms: linux/amd64,linux/arm/v7,linux/arm64
4455
push: true
4556
build-args: VERSION=${{ steps.get_tag.outputs.VERSION }}
46-
tags: docker.io/wollomatic/socket-proxy:${{ steps.get_tag.outputs.VERSION }},docker.io/wollomatic/socket-proxy:1
57+
tags: |
58+
docker.io/wollomatic/socket-proxy:${{ steps.get_tag.outputs.VERSION }}
59+
docker.io/wollomatic/socket-proxy:1
60+
ghcr.io/wollomatic/socket-proxy:${{ steps.get_tag.outputs.VERSION }}
61+
ghcr.io/wollomatic/socket-proxy:1
62+
63+
- name: Sign images for Docker
64+
run: cosign sign --yes --recursive --key env://COSIGN_PRIVATE_KEY docker.io/wollomatic/socket-proxy:${{ steps.get_tag.outputs.VERSION }}@${{ steps.build-and-push.outputs.digest }}
65+
env:
66+
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
67+
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
4768

48-
- name: Sign images for all platforms
49-
run: cosign sign --yes --key env://COSIGN_PRIVATE_KEY docker.io/wollomatic/socket-proxy:${{ steps.get_tag.outputs.VERSION }}@${{ steps.build-and-push.outputs.digest }}
69+
- name: Sign images for GHCR
70+
run: cosign sign --yes --recursive --key env://COSIGN_PRIVATE_KEY ghcr.io/wollomatic/socket-proxy:${{ steps.get_tag.outputs.VERSION }}@${{ steps.build-and-push.outputs.digest }}
5071
env:
5172
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
5273
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}

.github/workflows/docker-image-testing.yaml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,22 @@ jobs:
1010
build:
1111

1212
runs-on: ubuntu-latest
13+
env:
14+
GO111MODULE: on
1315

1416
steps:
1517
- name: Checkout
1618
uses: actions/checkout@v4
1719

1820
- name: Run Gosec Security Scanner
1921
uses: securego/gosec@master
22+
with:
23+
args: ./...
24+
25+
- name: Install Cosign
26+
uses: sigstore/[email protected]
27+
with:
28+
cosign-release: 'v2.4.3'
2029

2130
- name: Set up Docker Buildx
2231
uses: docker/setup-buildx-action@v3
@@ -27,6 +36,13 @@ jobs:
2736
username: ${{ secrets.DOCKERHUB_USERNAME }}
2837
password: ${{ secrets.DOCKERHUB_TOKEN }}
2938

39+
- name: Login to GitHub Container Registry
40+
uses: docker/login-action@v3
41+
with:
42+
registry: ghcr.io
43+
username: ${{ github.actor }}
44+
password: ${{ secrets.GITHUB_TOKEN }}
45+
3046
- name: Build and push Docker image
3147
uses: docker/build-push-action@v5
3248
id: build-and-push
@@ -35,4 +51,20 @@ jobs:
3551
platforms: linux/amd64,linux/arm64
3652
push: true
3753
build-args: VERSION=testing-${{ github.sha }}
38-
tags: docker.io/wollomatic/socket-proxy:testing,docker.io/wollomatic/socket-proxy:testing-${{ github.sha }}
54+
tags: |
55+
docker.io/wollomatic/socket-proxy:testing
56+
docker.io/wollomatic/socket-proxy:testing-${{ github.sha }}
57+
ghcr.io/wollomatic/socket-proxy:testing
58+
ghcr.io/wollomatic/socket-proxy:testing-${{ github.sha }}
59+
60+
- name: Sign Docker Hub image
61+
run: cosign sign --yes --recursive --key env://COSIGN_PRIVATE_KEY docker.io/wollomatic/socket-proxy:testing-${{ github.sha }}@${{ steps.build-and-push.outputs.digest }}
62+
env:
63+
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
64+
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
65+
66+
- name: Sign GitHub Container Registry image
67+
run: cosign sign --yes --recursive --key env://COSIGN_PRIVATE_KEY ghcr.io/wollomatic/socket-proxy:testing-${{ github.sha }}@${{ steps.build-and-push.outputs.digest }}
68+
env:
69+
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
70+
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}

README.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ It is designed with security in mind, so there are secure defaults and an additi
1111

1212
The allowlist is configured for each HTTP method separately using the Go regexp syntax, allowing fine-grained control over the allowed HTTP methods.
1313

14-
The source code is available on [GitHub: wollomatic/socket-proxy](https://github.com/wollomatic/socket-proxy).
14+
The source code is available on [GitHub: wollomatic/socket-proxy](https://github.com/wollomatic/socket-proxy)
15+
16+
> [!NOTE]
17+
> Starting with version 1.6.0, the socket-proxy container image is also available on GHCR.
1518
1619
## Getting Started
1720

@@ -23,14 +26,17 @@ You should know what you are doing. Never expose socket-proxy to a public networ
2326

2427
### Installing
2528

26-
The container image is available on [Docker Hub: wollomatic/socket-proxy](https://hub.docker.com/r/wollomatic/socket-proxy).
29+
The container image is available on [Docker Hub (wollomatic/socket-proxy)](https://hub.docker.com/r/wollomatic/socket-proxy)
30+
and on the [GitHub Container Registry (ghcr.io/wollomatic/socket-proxy)](https://hub.docker.com/r/wollomatic/socket-proxy).
31+
2732

28-
To pin one specific version, use the version tag (for example, `wollomatic/socket-proxy:1.0.1`).
29-
To always use the most recent version, use the `1` tag (`wollomatic/socket-proxy:1`). This tag will be valid as long as there is no breaking change in the deployment.
33+
To pin one specific version, use the version tag (for example, `wollomatic/socket-proxy:1.6.0` or `ghcr.io/wollomatic/socket-proxy:1.6.0`).
34+
To always use the most recent version, use the `1` tag (`wollomatic/socket-proxy:1` or `ghcr.io/wollomatic/socket-proxy:1`). This tag will be valid as long as there is no breaking change in the deployment.
3035

3136
There may be an additional docker image with the `testing`-tag. This image is only for testing. Likely, documentation for the `testing` image could only be found in the GitHub commit messages. It is not recommended to use the `testing` image in production.
3237

3338
Every socket-proxy release image is signed with Cosign. The public key is available on [GitHub: wollomatic/socket-proxy/main/cosign.pub](https://raw.githubusercontent.com/wollomatic/socket-proxy/main/cosign.pub) and [https://wollomatic.de/socket-proxy/cosign.pub](https://wollomatic.de/socket-proxy/cosign.pub). For more information, please refer to the [Security Policy](https://github.com/wollomatic/socket-proxy/blob/main/SECURITY.md).
39+
As of version 1.6, all multi-arch images are signed.
3440

3541
### Allowing access
3642

@@ -44,9 +50,6 @@ Socket-proxy listens per default only on `127.0.0.1`. Depending on what you need
4450

4551
#### Using a unix socket instead of a TCP listener
4652

47-
> [!CAUTION]
48-
> This is a new feature introduced in version 1.5.0. If you experience any issues, please feel free to open an GitHub issue.
49-
5053
If you want to proxy/filter the unix socket to a new unix socket instead to a TCP listener,
5154
you need to set the `-proxysocketendpoint` parameter or the `SP_PROXYSOCKETENDPOINT` env variable to the socket path of the new unix socket.
5255
This will also disable the TCP listener.
@@ -202,6 +205,8 @@ socket-proxy can be configured via command line parameters or via environment va
202205

203206
1.5 - allow unix socket as proxied/filtered endpoint
204207

208+
1.6 - Cosign: sign a multi-arch container image AND all referenced, discrete images. Image is also available on GHCR.
209+
205210
## License
206211

207212
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

cmd/socket-proxy/checksocketconnection.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func checkSocketAvailability(socketPath string) error {
2525
}
2626

2727
// startSocketWatchdog starts a watchdog that checks the socket availability every n seconds.
28-
func startSocketWatchdog(socketPath string, interval uint, stopOnWatchdog bool, exitChan chan int) {
28+
func startSocketWatchdog(socketPath string, interval int64, stopOnWatchdog bool, exitChan chan int) {
2929
ticker := time.NewTicker(time.Duration(interval) * time.Second)
3030
defer ticker.Stop()
3131

cmd/socket-proxy/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func main() {
141141

142142
// start the watchdog if configured
143143
if cfg.WatchdogInterval > 0 {
144-
go startSocketWatchdog(cfg.SocketPath, cfg.WatchdogInterval, cfg.StopOnWatchdog, internalQuit)
144+
go startSocketWatchdog(cfg.SocketPath, int64(cfg.WatchdogInterval), cfg.StopOnWatchdog, internalQuit) // #nosec G115 - we validated the integer size in config.go
145145
slog.Debug("watchdog running")
146146
}
147147

@@ -161,7 +161,7 @@ func main() {
161161
exitCode = value
162162
}
163163
// Try to shut down gracefully
164-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(cfg.ShutdownGraceTime)*time.Second)
164+
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(int64(cfg.ShutdownGraceTime))*time.Second) // #nosec G115 - we validated the integer size in config.go
165165
defer cancel()
166166
if err := srv.Shutdown(ctx); err != nil {
167167
slog.Warn("timeout stopping server", "error", err)

internal/config/config.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"flag"
66
"fmt"
77
"log/slog"
8+
"math"
89
"net"
910
"net/http"
1011
"os"
@@ -139,9 +140,15 @@ func InitConfig() (*Config, error) {
139140
flag.StringVar(&logLevel, "loglevel", defaultLogLevel, "set log level: DEBUG, INFO, WARN, ERROR")
140141
flag.UintVar(&proxyPort, "proxyport", defaultProxyPort, "tcp port to listen on")
141142
flag.UintVar(&cfg.ShutdownGraceTime, "shutdowngracetime", defaultShutdownGraceTime, "maximum time in seconds to wait for the server to shut down gracefully")
143+
if cfg.ShutdownGraceTime > math.MaxInt64 {
144+
return nil, fmt.Errorf("shutdowngracetime has to be smaller than %i", math.MaxInt64) // this maximum value has no practical significance
145+
}
142146
flag.StringVar(&cfg.SocketPath, "socketpath", defaultSocketPath, "unix socket path to connect to")
143147
flag.BoolVar(&cfg.StopOnWatchdog, "stoponwatchdog", defaultStopOnWatchdog, "stop the program when the socket gets unavailable (otherwise log only)")
144148
flag.UintVar(&cfg.WatchdogInterval, "watchdoginterval", defaultWatchdogInterval, "watchdog interval in seconds (0 to disable)")
149+
if cfg.WatchdogInterval > math.MaxInt64 {
150+
return nil, fmt.Errorf("watchdoginterval has to be smaller than %i", math.MaxInt64) // this maximum value has no practical significance
151+
}
145152
flag.StringVar(&cfg.ProxySocketEndpoint, "proxysocketendpoint", defaultProxySocketEndpoint, "unix socket endpoint (if set, used instead of the TCP listener)")
146153
flag.UintVar(&endpointFileMode, "proxysocketendpointfilemode", defaultProxySocketEndpointFileMode, "set the file mode of the unix socket endpoint")
147154
for i := range mr {
@@ -172,7 +179,10 @@ func InitConfig() (*Config, error) {
172179
return nil, errors.New("invalid log level " + logLevel + ": Supported levels are DEBUG, INFO, WARN, ERROR")
173180
}
174181

175-
cfg.ProxySocketEndpointFileMode = os.FileMode(endpointFileMode)
182+
if endpointFileMode > 0o777 {
183+
return nil, errors.New("file mode has to be between 0 and 0o777")
184+
}
185+
cfg.ProxySocketEndpointFileMode = os.FileMode(uint32(endpointFileMode))
176186

177187
// compile regexes for allowed requests
178188
cfg.AllowedRequests = make(map[string]*regexp.Regexp)

0 commit comments

Comments
 (0)