Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Build and Push Moroz Docker Image

on:
push:
branches:
- master
tags:
- 'v*'
pull_request:
branches:
- master
workflow_dispatch:

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
# set latest tag for master branch pushes
type=raw,value=latest,enable={{is_default_branch}}
# set PR tags for pull requests
type=ref,event=pr
# set version tags for releases
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
# set branch-sha for non-default branches
type=sha,prefix={{branch}}-,enable={{is_default_branch}}

- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
28 changes: 23 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
FROM alpine:3.6
FROM golang:1.23-alpine AS builder

RUN apk --update add \
ca-certificates
WORKDIR /app
RUN apk --no-cache add git ca-certificates
ADD . .
RUN go mod download

COPY ./build/linux/moroz /usr/bin/moroz
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o moroz ./cmd/moroz

CMD ["moroz"]
FROM alpine:latest
RUN apk --no-cache add ca-certificates
RUN addgroup -g 1001 -S moroz && \
adduser -u 1001 -S moroz -G moroz

WORKDIR /app
COPY --from=builder /app/moroz .

RUN chown -R moroz:moroz /app
USER moroz

EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1

CMD ["/app/moroz"]
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,13 @@ Assumes you have the `./server.crt` and `./server.key` files.
moroz -configs /path/to/configs/folder
```

# Kubernetes Deployment

Deploy to Kubernetes using kustomize:

```bash
kubectl apply -k deploy/
```

---
moroz icon by [Souvik Bhattacharjee](https://thenounproject.com/souvik502/) from the [Noun Project](https://thenounproject.com/).
63 changes: 63 additions & 0 deletions deploy/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: moroz-config
data:
global.toml: |
client_mode = "MONITOR"
# blocked_path_regex = "^(?:/Users)/.*"
# allowed_path_regex = "^(?:/Users)/.*"
batch_size = 100
enable_all_event_upload = true
enable_bundles = false
enable_transitive_rules = true
clean_sync = true
full_sync_interval = 600

[[rules]]
rule_type = "BINARY"
policy = "BLOCKLIST"
identifier = "2dc104631939b4bdf5d6bccab76e166e37fe5e1605340cf68dab919df58b8eda"
custom_msg = "blocklist firefox"

[[rules]]
rule_type = "TEAMID"
policy = "ALLOWLIST"
identifier = "EQHXZ8M8AV"
custom_msg = "allow google team id"

[[rules]]
rule_type = "SIGNINGID"
policy = "ALLOWLIST"
identifier = "EQHXZ8M8AV:com.google.Chrome"
custom_msg = "allow google chrome signing id"

[[rules]]
rule_type = "SIGNINGID"
policy = "BLOCKLIST"
identifier = "platform:com.apple.BluetoothFileExchange"
custom_msg = "block bluetooth file exchange.app"

[[rules]]
rule_type = "BINARY"
policy = "ALLOWLIST_COMPILER"
identifier = "60d79d1763fefb56716e4a36284300523eb4335c3726fb9070fa83074b02279e"
custom_msg = "allowlist go compiler component"

[[rules]]
rule_type = "BINARY"
policy = "ALLOWLIST_COMPILER"
identifier = "8e78770685d51324b78588fddc6afc2f8b6cef5231c27eeb97363cc437fec18a"
custom_msg = "allowlist go compiler component"

[[rules]]
rule_type = "BINARY"
policy = "ALLOWLIST_COMPILER"
identifier = "e88617cfd62809fb10e213c459a52f48e028fae4321e41134c4797465af886b6"
custom_msg = "allowlist go compiler component"

[[rules]]
rule_type = "BINARY"
policy = "ALLOWLIST_COMPILER"
identifier = "d867fca68bbd7db18e9ced231800e7535bc067852b1e530987bb7f57b5e3a02c"
custom_msg = "allowlist go compiler component"
79 changes: 79 additions & 0 deletions deploy/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: moroz-server
labels:
app.kubernetes.io/name: moroz-server
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: moroz-server
template:
metadata:
name: moroz-server
labels:
app.kubernetes.io/name: moroz-server
spec:
containers:
- name: moroz-server
image: ghcr.io/pmdroid/moroz:latest
args:
- /app/moroz
- --configs=/configs
- --use-tls=false
- --debug
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1001
runAsGroup: 1001
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
volumeMounts:
- mountPath: /configs
name: configs
readOnly: true
restartPolicy: Always
securityContext:
runAsNonRoot: true
runAsUser: 1001
runAsGroup: 1001
fsGroup: 1001
seccompProfile:
type: RuntimeDefault
automountServiceAccountToken: false
volumes:
- name: configs
configMap:
name: moroz-config
defaultMode: 0440
8 changes: 8 additions & 0 deletions deploy/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
metadata:
name: moroz
resources:
- deployment.yaml
- service.yaml
- configmap.yaml
13 changes: 13 additions & 0 deletions deploy/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: moroz-server
spec:
selector:
app.kubernetes.io/name: moroz-server
ports:
- protocol: TCP
port: 8080
name: http
targetPort: 8080
type: ClusterIP
3 changes: 3 additions & 0 deletions moroz/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ func AddHTTPRoutes(r *mux.Router, e Endpoints, logger log.Logger) {
options...,
))

r.Methods("GET").Path("/health").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
}

// errBadRoute is used for mux errors
Expand Down