Skip to content

Commit

Permalink
Removes coreos systemd go (#90)
Browse files Browse the repository at this point in the history
* removes coreos systemd-go use

* updates release.yml
  • Loading branch information
gradientsearch authored Jun 26, 2023
1 parent f3dab41 commit fd163c4
Show file tree
Hide file tree
Showing 17 changed files with 116 additions and 778 deletions.
13 changes: 12 additions & 1 deletion .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,16 @@ jobs:
- name: Execute tests
run: |
sudo apt update
sudo apt install -y make gcc curl libsystemd-dev
sudo apt install -y make rsyslog
sudo cp contrib/rsyslog/config/rsyslog.conf /etc/rsyslog.conf
sudo rm -rf /etc/rsyslog.d
sudo mkdir /etc/rsyslog.d
sudo cp -r contrib/rsyslog/config/rsyslog.d/* /etc/rsyslog.d/
sudo mkdir -p /var/log/audito-maldito
sudo mkdir -p /app-audit
sudo mkfifo /app-audit/app-events-output-test.log
sudo mkfifo /app-audit/sshd-pipe
sudo mkfifo /app-audit/audit-pipe
sudo systemctl restart rsyslog
sudo make integration-test
57 changes: 48 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
name: Release

name: Create and publish a api image

on:
push:
tags:
- v**
env:
REGISTRY: ghcr.io/metal-toolbox
API_IMAGE_NAME: audito-maldito/audito-maldito

jobs:
auto-release:
Expand All @@ -20,11 +24,46 @@ jobs:
with:
generate_release_notes: true

container-main:
uses: metal-toolbox/container-push/.github/workflows/container-push.yml@main
with:
name: audito-maldito
tag: ${{ github.ref_name }}
registry_org: ${{ github.repository }}
dockerfile_path: Dockerfile
platforms: linux/amd64,linux/arm64
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

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

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

- name: Get current date
id: date
run: echo "::set-output name=date::$(date -u +'%Y-%m-%dT%H:%M:%SZ')"

- name: Extract metadata (tags, labels) for Docker
id: meta-api
uses: docker/metadata-action@517f8b0c3b2daa800eac32a9a71024c8126d46a7
with:
images: ${{ env.REGISTRY }}/${{ env.API_IMAGE_NAME }}

- name: Build rsyslog and push Docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: "./contrib/rsyslog"
push: true
file: ./contrib/rsyslog/Dockerfile.ubuntu
tags: ${{ env.REGISTRY }}/${{ env.API_IMAGE_NAME }}:${{ github.ref_name }}-rsyslog
labels: ${{ steps.meta-api.outputs.labels }}

- name: Build and push Docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
push: true
file: Dockerfile
tags: ${{ env.REGISTRY }}/${{ env.API_IMAGE_NAME }}:${{ github.ref_name }}
labels: ${{ steps.meta-api.outputs.labels }}
15 changes: 8 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
FROM registry.fedoraproject.org/fedora-minimal:38 AS builder

RUN microdnf install -y systemd-devel golang git && microdnf clean all
FROM golang:1.20 as builder

WORKDIR /go/src/audito-maldito

# pre-copy/cache go.mod for pre-downloading dependencies and only redownloading them in subsequent builds if they change
COPY go.mod go.sum ./
RUN go mod download && go mod verify

COPY . .
COPY cmd ./cmd
COPY ingesters ./ingesters
COPY internal ./internal
COPY processors ./processors
COPY main.go .

RUN go build -o audito-maldito

# Not using distroless nor scratch because we need the systemd shared libraries
FROM registry.fedoraproject.org/fedora-minimal:38

FROM ubuntu:22.04
# NOTE(jaosorior): Yes, we need to be the root user for this case.
# We need access to the journal's privileged log entries and the audit log in the future.
USER 0

COPY --from=builder /go/src/audito-maldito/audito-maldito /usr/bin/audito-maldito

ENTRYPOINT [ "/usr/bin/audito-maldito" ]
ENTRYPOINT [ "/usr/bin/audito-maldito" ]
157 changes: 6 additions & 151 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,17 @@ package cmd

import (
"context"
"flag"
"net/http"
"os"
"strconv"
"time"

"github.com/metal-toolbox/auditevent"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"golang.org/x/sync/errgroup"

"github.com/metal-toolbox/audito-maldito/ingesters/journald"
"github.com/metal-toolbox/audito-maldito/internal/common"
"github.com/metal-toolbox/audito-maldito/internal/health"
"github.com/metal-toolbox/audito-maldito/internal/metrics"
"github.com/metal-toolbox/audito-maldito/internal/util"
"github.com/metal-toolbox/audito-maldito/processors/sshd"
"github.com/metal-toolbox/audito-maldito/processors/varlogsecure"
)

const usage = `audito-maldito
Expand Down Expand Up @@ -56,119 +48,6 @@ type metricsConfig struct {
auditLogWriteTimeSecondThreshold int
}

type appConfig struct {
bootID string
auditlogpath string
auditLogDirPath string
metricsConfig metricsConfig
logLevel zapcore.Level
}

func parseFlags(osArgs []string) (*appConfig, error) {
flagSet := flag.NewFlagSet(osArgs[0], flag.ContinueOnError)

config := &appConfig{
logLevel: zapcore.InfoLevel,
}

// This is just needed for testing purposes. If it's empty we'll use the current boot ID
flagSet.StringVar(&config.bootID, "boot-id", "", "Optional Linux boot ID to use when reading from the journal")
flagSet.StringVar(&config.auditlogpath, "audit-log-path", "/app-audit/audit.log", "Path to the audit log file")
flagSet.StringVar(&config.auditLogDirPath, "audit-dir-path", "/var/log/audit",
"Path to the Linux audit log directory")
flagSet.Var(&config.logLevel, "log-level", "Set the log level according to zapcore.Level")
flagSet.BoolVar(&config.metricsConfig.enableMetrics, "metrics", false, "Enable Prometheus HTTP /metrics server")
flagSet.BoolVar(&config.metricsConfig.enableHealthz, "healthz", false, "Enable HTTP health endpoints server")
flagSet.BoolVar(&config.metricsConfig.enableAuditMetrics, "audit-metrics", false, "Enable Prometheus audit metrics")
flagSet.DurationVar(&config.metricsConfig.httpServerReadTimeout, "http-server-read-timeout",
DefaultHTTPServerReadTimeout, "HTTP server read timeout")
flagSet.DurationVar(&config.metricsConfig.httpServerReadHeaderTimeout, "http-server-read-header-timeout",
DefaultHTTPServerReadHeaderTimeout, "HTTP server read header timeout")
flagSet.DurationVar(
&config.metricsConfig.auditMetricsSecondsInterval,
"audit-seconds-interval",
DefaultAuditCheckInterval,
"Interval in seconds to collect audit metrics")
flagSet.IntVar(
&config.metricsConfig.auditLogWriteTimeSecondThreshold,
"audit-log-last-modify-seconds-threshold",
DefaultAuditModifyTimeThreshold,
"seconds since last write to audit.log before alerting")

flagSet.Usage = func() {
os.Stderr.WriteString(usage)
flagSet.PrintDefaults()
os.Exit(1)
}

if err := flagSet.Parse(osArgs[1:]); err != nil {
return nil, err
}

return config, nil
}

func runProcessorsForSSHLogins(
ctx context.Context,
logins chan<- common.RemoteUserLogin,
eg *errgroup.Group,
distro util.DistroType,
mid string,
nodename string,
bootID string,
lastReadJournalTS uint64,
eventWriter *auditevent.EventWriter,
h *health.Health,
pprov *metrics.PrometheusMetricsProvider,
) {
sshdProcessor := sshd.NewSshdProcessor(ctx, logins, nodename, mid, eventWriter, pprov)

//nolint:exhaustive // In this case it's actually simpler to just default to journald
switch distro {
case util.DistroRocky:
h.AddReadiness(varlogsecure.VarLogSecureComponentName)

// TODO: handle last read timestamp
eg.Go(func() error {
vls := varlogsecure.VarLogSecure{
L: logger,
Logins: logins,
NodeName: nodename,
MachineID: mid,
AuWriter: eventWriter,
Health: h,
Metrics: pprov,
SshdProcessor: sshdProcessor,
}

err := vls.Read(ctx)
logger.Infof("varlogsecure worker exited (%v)", err)
return err
})
default:
h.AddReadiness(journald.JournaldReaderComponentName)

eg.Go(func() error {
jp := journald.Processor{
BootID: bootID,
MachineID: mid,
NodeName: nodename,
Distro: distro,
EventW: eventWriter,
Logins: logins,
CurrentTS: lastReadJournalTS,
Health: h,
Metrics: pprov,
SshdProcessor: sshdProcessor,
}

err := jp.Read(ctx)
logger.Infof("journald worker exited (%v)", err)
return err
})
}
}

// handleMetricsAndHealth starts a HTTP server on port 2112 to serve metrics
// and health endpoints.
//
Expand Down Expand Up @@ -208,44 +87,20 @@ func handleMetricsAndHealth(ctx context.Context, mc metricsConfig, eg *errgroup.
}
}

// lastReadJournalTimeStamp returns the last-read journal entry's timestamp
// or a sensible default if the timestamp cannot be loaded.
func lastReadJournalTimeStamp() uint64 {
lastRead, err := common.GetLastRead()
switch {
case err != nil:
lastRead = uint64(time.Now().UnixMicro())

logger.Warnf("failed to read last read timestamp for journal - "+
"reading from current time (reason: '%s')", err.Error())
case lastRead == 0:
lastRead = uint64(time.Now().UnixMicro())

logger.Info("last read timestamp for journal is zero - " +
"reading from current time")
default:
logger.Infof("last read timestamp for journal is: '%d'", lastRead)
}

return lastRead
}

func handleAuditLogMetrics(
ctx context.Context,
mc metricsConfig,
eg *errgroup.Group,
pprov *metrics.PrometheusMetricsProvider,
auditMetricsSecondsInterval time.Duration,
auditLogWriteTimeSecondThreshold int,
enableAuditMetrics bool,
) {
if !enableAuditMetrics {
if !mc.enableAuditMetrics {
return
}

auditLogFilePath := "/var/log/audit/audit.log"

eg.Go(func() error {
ticker := time.NewTicker(auditMetricsSecondsInterval)
ticker := time.NewTicker(mc.auditMetricsSecondsInterval)
defer ticker.Stop()

for {
Expand All @@ -257,10 +112,10 @@ func handleAuditLogMetrics(
continue
}

if time.Since(s.ModTime()).Seconds() > float64(auditLogWriteTimeSecondThreshold) {
pprov.SetAuditLogCheck(0, strconv.Itoa(auditLogWriteTimeSecondThreshold))
if time.Since(s.ModTime()).Seconds() > float64(mc.auditLogWriteTimeSecondThreshold) {
pprov.SetAuditLogCheck(0, strconv.Itoa(mc.auditLogWriteTimeSecondThreshold))
} else {
pprov.SetAuditLogCheck(1, strconv.Itoa(auditLogWriteTimeSecondThreshold))
pprov.SetAuditLogCheck(1, strconv.Itoa(mc.auditLogWriteTimeSecondThreshold))
}

pprov.SetAuditLogModifyTime(float64(s.ModTime().Unix()))
Expand Down
Loading

0 comments on commit fd163c4

Please sign in to comment.