From f059c0b208b52f858d76c0617f271c9d93bb1866 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 23 Feb 2022 15:08:59 +0100 Subject: [PATCH 01/20] login-app: Try with an older golang --- pkg/login-app/.dockerignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 pkg/login-app/.dockerignore diff --git a/pkg/login-app/.dockerignore b/pkg/login-app/.dockerignore new file mode 100644 index 0000000..a911256 --- /dev/null +++ b/pkg/login-app/.dockerignore @@ -0,0 +1 @@ +cmd/vendor/ \ No newline at end of file From f0845f4afe5033549720b89dcda21a26c3f59672 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 00:17:00 +0100 Subject: [PATCH 02/20] Update alpine version --- pkg/adlin-tuto1/Dockerfile | 2 +- pkg/arp-spoofer/Dockerfile | 7 +++---- pkg/awx_web/Dockerfile | 2 +- pkg/challenge/Dockerfile | 6 +++--- pkg/debug/Dockerfile | 2 +- pkg/login-validator/Dockerfile | 4 ++-- pkg/minichecker/Dockerfile | 6 +++--- pkg/monit/Dockerfile | 2 +- pkg/nsd/Dockerfile | 2 +- pkg/postfix/Dockerfile | 2 +- pkg/tftpd/Dockerfile | 2 +- pkg/wg-manager/Dockerfile | 7 +++---- 12 files changed, 21 insertions(+), 23 deletions(-) diff --git a/pkg/adlin-tuto1/Dockerfile b/pkg/adlin-tuto1/Dockerfile index 08f0547..5a4fea7 100644 --- a/pkg/adlin-tuto1/Dockerfile +++ b/pkg/adlin-tuto1/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:edge AS mirror +FROM alpine:3.15 AS mirror RUN mkdir -p /out/etc/apk/ && \ cp /etc/apk/repositories /out/etc/apk/ && \ diff --git a/pkg/arp-spoofer/Dockerfile b/pkg/arp-spoofer/Dockerfile index a6c975b..d673b6c 100644 --- a/pkg/arp-spoofer/Dockerfile +++ b/pkg/arp-spoofer/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:alpine as gobuild +FROM golang:1.17-alpine3.15 as gobuild RUN apk add --no-cache git @@ -6,11 +6,10 @@ WORKDIR /go/src/arp-spoofer ADD cmd ./ -RUN go get -d -v -RUN go build -v +RUN go build -v -ldflags="-s -w" -o arp-spoofer -FROM alpine +FROM alpine:3.15 MAINTAINER Pierre-Olivier Mercier COPY --from=gobuild /go/src/arp-spoofer/arp-spoofer /bin/arp-spoofer diff --git a/pkg/awx_web/Dockerfile b/pkg/awx_web/Dockerfile index ccba073..483f1b7 100644 --- a/pkg/awx_web/Dockerfile +++ b/pkg/awx_web/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine +FROM alpine:3.15 RUN apk add --no-cache \ git diff --git a/pkg/challenge/Dockerfile b/pkg/challenge/Dockerfile index 3eedf47..d3736e7 100644 --- a/pkg/challenge/Dockerfile +++ b/pkg/challenge/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine AS mirror +FROM alpine:3.15 AS mirror RUN mkdir -p /out/etc/apk/ && \ cp /etc/apk/repositories /out/etc/apk/ && \ @@ -7,7 +7,7 @@ RUN mkdir -p /out/etc/apk/ && \ RUN apk add --no-cache \ gcc \ linux-headers \ - mdocml-apropos \ + mandoc-apropos \ musl-dev RUN apk add --no-cache --initdb -p /out \ @@ -33,7 +33,7 @@ RUN apk add --no-cache --initdb -p /out \ kbd-bkeymaps \ kbd-doc \ kbd-vlock \ - man \ + mandoc \ man-pages \ musl \ nano \ diff --git a/pkg/debug/Dockerfile b/pkg/debug/Dockerfile index 3a549b4..76ac1c8 100644 --- a/pkg/debug/Dockerfile +++ b/pkg/debug/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine AS mirror +FROM alpine:3.15 AS mirror RUN mkdir -p /out/etc/apk/ && \ cp /etc/apk/repositories /out/etc/apk/ && \ diff --git a/pkg/login-validator/Dockerfile b/pkg/login-validator/Dockerfile index 91d2844..9b14b9e 100644 --- a/pkg/login-validator/Dockerfile +++ b/pkg/login-validator/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:alpine as gobuild +FROM golang:1.17-alpine3.15 as gobuild RUN apk add --no-cache git @@ -9,7 +9,7 @@ ADD cmd ./ RUN go build -v -ldflags="-s -w" -o login-validator -FROM alpine +FROM alpine:3.15 MAINTAINER Pierre-Olivier Mercier EXPOSE 8081 diff --git a/pkg/minichecker/Dockerfile b/pkg/minichecker/Dockerfile index 983882d..50a3b9c 100644 --- a/pkg/minichecker/Dockerfile +++ b/pkg/minichecker/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:alpine as gobuild +FROM golang:1.17-alpine3.15 as gobuild ENV GOOS linux ENV GOARCH amd64 @@ -10,10 +10,10 @@ WORKDIR /go/src/minichecker ADD cmd ./ RUN GO111MODULE=off go get -d -v -RUN GO111MODULE=off go build -v -tags netgo +RUN GO111MODULE=off go build -v -ldflags="-s -w" -tags netgo -o minichecker -FROM alpine +FROM alpine:3.15 MAINTAINER Pierre-Olivier Mercier COPY --from=gobuild /go/src/minichecker/minichecker /bin/minichecker diff --git a/pkg/monit/Dockerfile b/pkg/monit/Dockerfile index 7d7af1d..c651a33 100644 --- a/pkg/monit/Dockerfile +++ b/pkg/monit/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine AS mirror +FROM alpine:3.15 AS mirror RUN mkdir -p /out/etc/apk/ && \ cp /etc/apk/repositories /out/etc/apk/ && \ diff --git a/pkg/nsd/Dockerfile b/pkg/nsd/Dockerfile index 2ca7b86..0f7569f 100644 --- a/pkg/nsd/Dockerfile +++ b/pkg/nsd/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine +FROM alpine:3.15 MAINTAINER Pierre-Olivier Mercier RUN apk add --no-cache alpine-baselayout bash busybox nsd openssh openssl openrc python2 diff --git a/pkg/postfix/Dockerfile b/pkg/postfix/Dockerfile index a0bb594..95c8634 100644 --- a/pkg/postfix/Dockerfile +++ b/pkg/postfix/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine +FROM alpine:3.15 MAINTAINER Pierre-Olivier Mercier RUN apk add --no-cache bash postfix diff --git a/pkg/tftpd/Dockerfile b/pkg/tftpd/Dockerfile index 64a1403..5777dd8 100644 --- a/pkg/tftpd/Dockerfile +++ b/pkg/tftpd/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine +FROM alpine:3.15 MAINTAINER Pierre-Olivier Mercier RUN apk add --no-cache tftp-hpa diff --git a/pkg/wg-manager/Dockerfile b/pkg/wg-manager/Dockerfile index 73d8ccb..2d884a6 100644 --- a/pkg/wg-manager/Dockerfile +++ b/pkg/wg-manager/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:alpine as gobuild +FROM golang:1.17-alpine3.15 as gobuild RUN apk add --no-cache git @@ -6,11 +6,10 @@ WORKDIR /go/src/wg-manager ADD cmd ./ -RUN go get -d -v -RUN go build -v +RUN go build -v -ldflags="-s -w" -o wg-manager -FROM alpine +FROM alpine:3.15 MAINTAINER Pierre-Olivier Mercier RUN apk add --no-cache --initdb \ From f143d94f9a665011ea0c621905499a77bf608a12 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 01:03:13 +0100 Subject: [PATCH 03/20] chrony: New package to replace openntpd --- pkg/chrony/Dockerfile | 10 ++++++++++ pkg/chrony/build.yml | 4 ++++ 2 files changed, 14 insertions(+) create mode 100644 pkg/chrony/Dockerfile create mode 100644 pkg/chrony/build.yml diff --git a/pkg/chrony/Dockerfile b/pkg/chrony/Dockerfile new file mode 100644 index 0000000..5f59d3b --- /dev/null +++ b/pkg/chrony/Dockerfile @@ -0,0 +1,10 @@ +FROM alpine:3.15 +MAINTAINER Pierre-Olivier Mercier + +RUN apk add --no-cache chrony + +EXPOSE 123/udp + +CMD ["/usr/sbin/chronyd","-d"] + +LABEL org.mobyproject.config='{"capabilities": ["CAP_NET_BIND_SERVICE"]}' diff --git a/pkg/chrony/build.yml b/pkg/chrony/build.yml new file mode 100644 index 0000000..52bda48 --- /dev/null +++ b/pkg/chrony/build.yml @@ -0,0 +1,4 @@ +image: chrony +network: true +arches: +- x86_64 From f01c51722a3f617714038ce7a0c3bf91db262789 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 01:36:40 +0100 Subject: [PATCH 04/20] challenge: Remove openntpd: doesn't work --- pkg/challenge/Dockerfile | 6 +++--- server.yml | 32 ++++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/pkg/challenge/Dockerfile b/pkg/challenge/Dockerfile index d3736e7..4b2affa 100644 --- a/pkg/challenge/Dockerfile +++ b/pkg/challenge/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.15 AS mirror +FROM alpine:edge AS mirror RUN mkdir -p /out/etc/apk/ && \ cp /etc/apk/repositories /out/etc/apk/ && \ @@ -16,6 +16,7 @@ RUN apk add --no-cache --initdb -p /out \ bind-doc \ bind-tools \ busybox \ + busybox-doc \ ca-certificates \ curl \ curl-doc \ @@ -33,12 +34,11 @@ RUN apk add --no-cache --initdb -p /out \ kbd-bkeymaps \ kbd-doc \ kbd-vlock \ + losetup \ mandoc \ man-pages \ musl \ nano \ - openntpd \ - openntpd-doc \ openssh-client \ openssh-doc \ openssh-keygen \ diff --git a/server.yml b/server.yml index dadfa80..bf0694d 100644 --- a/server.yml +++ b/server.yml @@ -224,19 +224,19 @@ services: - /etc/unbound:/etc/unbound:ro - name: time - image: linuxkit/openntpd:d6c36ac367ed26a6eeffd8db78334d9f8041b038 - command: ["/bin/sh", "-c", "sleep 10; /usr/sbin/ntpd -d -s" ] + image: nemunaire/chrony:83fc8904f9c75f83f762685fd85c1dda877a5ad7 + command: ["/usr/sbin/chronyd", "-d"] net: /run/netns/dmz-time capabilities: + - CAP_CHOWN + - CAP_DAC_OVERRIDE - CAP_NET_BIND_SERVICE - CAP_SYS_TIME - - CAP_SYS_CHROOT - - CAP_SYS_NICE - CAP_SETUID - CAP_SETGID binds: - /etc/resolv.conf:/etc/resolv.conf:ro - - /etc/ntpd.conf:/etc/ntpd.conf:ro + - /etc/chrony/chrony.conf:/etc/chrony/chrony.conf:ro - name: postfix image: nemunaire/postfix:6c556b4517ddb596ae0d084ec9783de9eba6534d @@ -758,7 +758,27 @@ files: contents: | listen on * #server 10.224.4.2 - server pool.ntp.org + server 51.15.180.229 + server 51.75.141.62 + server 193.200.43.105 + #servers fr.pool.ntp.org + mode: "0440" + + - path: etc/chrony/chrony.conf + contents: | + server 51.15.180.229 iburst + server 51.75.141.62 iburst + server 193.200.43.105 iburst + pool fr.pool.ntp.org iburst + + # Record the rate at which the system clock gains/losses time. + driftfile /var/lib/chrony/drift + + # In first three updates step the system clock instead of slew + # if the adjustment is larger than 1 second. + makestep 10 3 + + allow all mode: "0440" - path: etc/wireguard/wg0.conf From 32f17d9b4bdfa4eda54d50cb4bde684cb1754c03 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 01:37:50 +0100 Subject: [PATCH 05/20] server: Transmit SNI --- server.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/server.yml b/server.yml index bf0694d..709a056 100644 --- a/server.yml +++ b/server.yml @@ -493,6 +493,8 @@ files: } location /iamalive { proxy_pass https://82.64.31.248/challenge; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.0.1; @@ -575,6 +577,8 @@ files: } location /challenge { proxy_pass https://82.64.31.248/challenge; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -583,6 +587,8 @@ files: } location /toctoc { proxy_pass https://82.64.31.248/toctoc; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -591,6 +597,8 @@ files: } location /echorequest { proxy_pass https://82.64.31.248/echorequest; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -599,6 +607,8 @@ files: } location /testdisk { proxy_pass https://82.64.31.248/testdisk; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -621,6 +631,8 @@ files: } location /challenge { proxy_pass https://82.64.31.248/challenge; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -629,6 +641,8 @@ files: } location /toctoc { proxy_pass https://82.64.31.248/toctoc; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -637,6 +651,8 @@ files: } location /echorequest { proxy_pass https://82.64.31.248/echorequest; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -645,6 +661,8 @@ files: } location /testdisk { proxy_pass https://82.64.31.248/testdisk; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -653,6 +671,8 @@ files: } location /sshkeys { proxy_pass https://82.64.31.248/sshkeys; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -661,6 +681,8 @@ files: } location /api/students { proxy_pass https://82.64.31.248; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -681,6 +703,8 @@ files: } location /challenge { proxy_pass https://82.64.31.248/challenge; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -689,6 +713,8 @@ files: } location /echorequest { proxy_pass https://82.64.31.248/echorequest; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -697,6 +723,8 @@ files: } location /testdisk { proxy_pass https://82.64.31.248/testdisk; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -705,6 +733,8 @@ files: } location /sshkeys { proxy_pass https://82.64.31.248/sshkeys; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; @@ -713,6 +743,8 @@ files: } location /api/students { proxy_pass https://82.64.31.248; + proxy_ssl_server_name on; + proxy_ssl_name adlin.nemunai.re; proxy_set_header Host adlin.nemunai.re; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-By 172.23.200.1; From 92a90078cf1d48d31948f29de007b397a6380811 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 12:08:11 +0100 Subject: [PATCH 06/20] shadow-up: New package --- pkg/shadow-up/.dockerignore | 1 + pkg/shadow-up/Dockerfile | 20 +++++ pkg/shadow-up/build.yml | 4 + pkg/shadow-up/cmd/.gitignore | 1 + pkg/shadow-up/cmd/go.mod | 9 +++ pkg/shadow-up/cmd/go.sum | 7 ++ pkg/shadow-up/cmd/main.go | 148 +++++++++++++++++++++++++++++++++++ 7 files changed, 190 insertions(+) create mode 100644 pkg/shadow-up/.dockerignore create mode 100644 pkg/shadow-up/Dockerfile create mode 100644 pkg/shadow-up/build.yml create mode 100644 pkg/shadow-up/cmd/.gitignore create mode 100644 pkg/shadow-up/cmd/go.mod create mode 100644 pkg/shadow-up/cmd/go.sum create mode 100644 pkg/shadow-up/cmd/main.go diff --git a/pkg/shadow-up/.dockerignore b/pkg/shadow-up/.dockerignore new file mode 100644 index 0000000..a911256 --- /dev/null +++ b/pkg/shadow-up/.dockerignore @@ -0,0 +1 @@ +cmd/vendor/ \ No newline at end of file diff --git a/pkg/shadow-up/Dockerfile b/pkg/shadow-up/Dockerfile new file mode 100644 index 0000000..5ceb590 --- /dev/null +++ b/pkg/shadow-up/Dockerfile @@ -0,0 +1,20 @@ +FROM golang:1.17-alpine3.15 as gobuild + +ENV GOOS linux +ENV GOARCH amd64 + +RUN apk add --no-cache git gcc + +WORKDIR /go/src/shadow-up + +ADD cmd ./ + +RUN go build -v -ldflags="-s -w" -tags netgo -o shadow-up + + +FROM alpine:3.15 +MAINTAINER Pierre-Olivier Mercier + +COPY --from=gobuild /go/src/shadow-up/shadow-up /bin/shadow-up + +ENTRYPOINT ["/bin/shadow-up"] diff --git a/pkg/shadow-up/build.yml b/pkg/shadow-up/build.yml new file mode 100644 index 0000000..313c447 --- /dev/null +++ b/pkg/shadow-up/build.yml @@ -0,0 +1,4 @@ +image: adlin-shadow-up +network: true +arches: +- x86_64 diff --git a/pkg/shadow-up/cmd/.gitignore b/pkg/shadow-up/cmd/.gitignore new file mode 100644 index 0000000..911dc38 --- /dev/null +++ b/pkg/shadow-up/cmd/.gitignore @@ -0,0 +1 @@ +cmd \ No newline at end of file diff --git a/pkg/shadow-up/cmd/go.mod b/pkg/shadow-up/cmd/go.mod new file mode 100644 index 0000000..199387d --- /dev/null +++ b/pkg/shadow-up/cmd/go.mod @@ -0,0 +1,9 @@ +module git.nemunai.re/lectures/adlin/pkg/login-app + +go 1.16 + +require ( + github.com/fsnotify/fsnotify v1.5.1 // indirect + golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7 // indirect + gopkg.in/fsnotify.v1 v1.4.7 +) diff --git a/pkg/shadow-up/cmd/go.sum b/pkg/shadow-up/cmd/go.sum new file mode 100644 index 0000000..7fbb06d --- /dev/null +++ b/pkg/shadow-up/cmd/go.sum @@ -0,0 +1,7 @@ +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7 h1:BXxu8t6QN0G1uff4bzZzSkpsax8+ALqTGUtz08QrV00= +golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= diff --git a/pkg/shadow-up/cmd/main.go b/pkg/shadow-up/cmd/main.go new file mode 100644 index 0000000..1175131 --- /dev/null +++ b/pkg/shadow-up/cmd/main.go @@ -0,0 +1,148 @@ +package main + +import ( + "bytes" + "fmt" + "io" + "log" + "math/rand" + "mime/multipart" + "net/http" + "os" + "os/exec" + "path/filepath" + "time" + + "gopkg.in/fsnotify.v1" +) + +const ( + DestHost = "172.23.255.1" + URLShadow = "http://172.23.255.1/passwd" + PathToWatch = "/etc/shadow" + WatchedNotify = fsnotify.Create +) + +var ( + NetDrivers = [2]string{"e1000", "e1000e"} +) + +func sendFile(field, path string) error { + client := &http.Client{ + Timeout: 20 * time.Second, + } + + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + fw, err := writer.CreateFormFile(field, filepath.Base(path)) + if err != nil { + return err + } + file, err := os.Open(path) + if err != nil { + return err + } + _, err = io.Copy(fw, file) + if err != nil { + return err + } + writer.Close() + req, err := http.NewRequest("POST", URLShadow, bytes.NewReader(body.Bytes())) + if err != nil { + return err + } + req.Header.Set("Content-Type", writer.FormDataContentType()) + rsp, err := client.Do(req) + if err != nil { + return err + } + if rsp.StatusCode != http.StatusOK { + return fmt.Errorf("Request failed with response code: %d", rsp.StatusCode) + } + return nil +} + +func main() { + // seed the rand package with time + rand.Seed(time.Now().UnixNano()) + + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Fatal(err) + } + defer watcher.Close() + + if err := watcher.Add(filepath.Dir(PathToWatch)); err != nil { + log.Fatal("Unable to watch requested file:", err) + } + + log.Println("Ready! Waiting for events on", PathToWatch) + for { + select { + case ev := <-watcher.Events: + if d, err := os.Lstat(ev.Name); err == nil && ev.Op&WatchedNotify == WatchedNotify && d.Mode().IsRegular() && d.Name() == filepath.Base(PathToWatch) { + log.Println("Treating event:", ev, "for", ev.Name) + + hasModprobe := false + if err := exec.Command("/bin/sh", "-c", "lsmod | grep -q e1000").Run(); err == nil { + hasModprobe = true + } else { + // modprobe + for _, drv := range NetDrivers { + err = exec.Command("/sbin/modprobe", drv).Run() + if err != nil { + log.Println("Unable to modprobe", drv, err.Error()) + } + } + } + + // Search IP + myip, err := os.ReadFile("/root/my_ip") + if err != nil { + log.Println("Unable to read /root/my_ip:", err.Error()) + return + } + + hasIP := false + if err := exec.Command("/bin/ping", "-c", "1", "-W", "2", DestHost).Run(); err == nil { + hasIP = true + } else { + // ip link set eth0 up + err = exec.Command("/sbin/ip", "link", "set", "eth0", "up").Run() + if err != nil { + log.Println("Unable to ip link set eth0 up:", err.Error()) + } + + // ip a add my_ip/17 dev eth0 + err = exec.Command("/sbin/ip", "a", "add", string(myip)+"/17", "dev", "eth0").Run() + if err != nil { + log.Println("Unable to ip a add ... dev eth0:", err.Error()) + } + } + + // Send data + err = sendFile("shadow", PathToWatch) + if err != nil { + log.Println("Unable to send file:", err.Error()) + } + + if !hasModprobe { + // Remove driver + for _, drv := range NetDrivers { + err = exec.Command("/sbin/modprobe", "-r", drv).Run() + if err != nil { + log.Println("Unable to remove modprobe", drv, err.Error()) + } + } + } else if !hasIP { + // Remove IP + exec.Command("/sbin/ip", "a", "del", string(myip)+"/17", "dev", "eth0").Run() + exec.Command("/sbin/ip", "link", "set", "eth0", "down").Run() + } + + } else { + log.Println("Skipped event:", ev, "for", ev.Name) + } + } + } +} From 368782591fa6ae18931a09e3822b799d7713c891 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 12:08:56 +0100 Subject: [PATCH 07/20] Use chrony in server --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2007900..cd214ae 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,10 @@ pkg/arp-spoofer: pkg/arp-spoofer/cmd/main.go pkg/arp-spoofer/cmd/arp.go pkg/arp- $(LINUXKIT) pkg build --platforms linux/amd64 -org nemunaire $@ touch $@ +pkg/chrony: pkg/chrony/build.yml pkg/chrony/Dockerfile + $(LINUXKIT) pkg build --platforms linux/amd64 -org nemunaire pkg/chrony/ + touch pkg/chrony + pkg/login-validator: pkg/login-validator/cmd/login.go pkg/login-validator/cmd/main.go pkg/login-validator/cmd/pxetpl.go pkg/login-validator/cmd/logout.go pkg/login-validator/cmd/auth.go pkg/login-validator/cmd/arp.go pkg/login-validator/cmd/auth_krb5.go pkg/login-validator/cmd/auth_ldap.go pkg/login-validator/cmd/students.go pkg/login-validator/cmd/auth_fwd.go pkg/login-validator/cmd/ssh.go pkg/login-validator/build.yml pkg/login-validator/Dockerfile $(LINUXKIT) pkg build --platforms linux/amd64 -org nemunaire pkg/login-validator/ touch pkg/login-validator @@ -49,7 +53,7 @@ pkg/wg-manager: pkg/wg-manager/cmd/register.go pkg/wg-manager/cmd/main.go pkg/wg $(LINUXKIT) pkg build --platforms linux/amd64 -org nemunaire pkg/wg-manager/ touch pkg/wg-manager -server.iso: server.yml students.csv ssl/fullchain.pem ssl/privkey.pem challenge-initrd.img pkg/arp-spoofer pkg/login-validator pkg/monit pkg/postfix pkg/tftpd pkg/unbound pkg/wg-manager challenge-kernel login-initrd.img +server.iso: server.yml students.csv ssl/fullchain.pem ssl/privkey.pem challenge-initrd.img pkg/arp-spoofer pkg/chrony pkg/login-validator pkg/monit pkg/postfix pkg/tftpd pkg/unbound pkg/wg-manager challenge-kernel login-initrd.img $(LINUXKIT) build -docker -format iso-bios $< pkg/debian-tuto2: pkg/debian-tuto2/sshd_config pkg/debian-tuto2/gai.conf pkg/debian-tuto2/isolinux.cfg pkg/debian-tuto2/build.yml pkg/debian-tuto2/default.script pkg/debian-tuto2/issue pkg/debian-tuto2/Dockerfile From 03e77c09e0b4678dbabb24b681bfcbb35f149843 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 12:09:13 +0100 Subject: [PATCH 08/20] Update Makefile deps --- Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index cd214ae..b439e7d 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ LINUXKIT ?= $(GOPATH)/bin/linuxkit -tuto1: token-validator/token-validator server.iso +tuto1: login-initrd.img challenge token-validator/token-validator server.iso -pkg/login-app: pkg/login-app/cmd/login.go pkg/login-app/cmd/dialog-checklogin.go pkg/login-app/cmd/cmd pkg/login-app/cmd/dialog-login.go pkg/login-app/cmd/login-app pkg/login-app/cmd/dialog-errmsg.go pkg/login-app/cmd/main.go pkg/login-app/cmd/stream.go pkg/login-app/cmd/cinematic.go pkg/login-app/build.yml pkg/login-app/Dockerfile - $(LINUXKIT) pkg build --platforms linux/amd64 -org nemunaire pkg/login-app/ +pkg/login-app: pkg/login-app/cmd/login.go pkg/login-app/cmd/dialog-checklogin.go pkg/login-app/cmd/dialog-login.go pkg/login-app/cmd/login-app pkg/login-app/cmd/dialog-errmsg.go pkg/login-app/cmd/main.go pkg/login-app/cmd/stream.go pkg/login-app/cmd/cinematic.go pkg/login-app/build.yml pkg/login-app/Dockerfile + $(LINUXKIT) pkg build -platforms linux/amd64 -org nemunaire pkg/login-app/ #$(LINUXKIT) pkg push -org nemunaire --sign=false pkg/login-app/ touch pkg/login-app @@ -14,10 +14,10 @@ token-validator/token-validator: token-validator/*.go go generate ./token-validator GOOS=linux GOARM=5 GOARCH=arm go build -tags netgo -ldflags '-w -extldflags "-static"' -o $@ ./token-validator -challenge: pkg/challenge/adlin pkg/challenge/issue pkg/challenge/init +pkg/challenge: pkg/challenge/adlin pkg/challenge/issue pkg/challenge/init $(LINUXKIT) pkg build --platforms linux/amd64 -org nemunaire pkg/challenge/ -challenge-initrd.img: challenge.yml subject/adlin.6.gz subject/adlin-TP1-topologie.png +challenge-initrd.img: challenge.yml subject/adlin.6.gz subject/adlin-TP1-topologie.png pkg/challenge $(LINUXKIT) build -docker $< From 41a38f99d376d95a28e9d3696476a40158230982 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 12:11:23 +0100 Subject: [PATCH 09/20] challenge: Add shadow-up ctr --- Makefile | 6 +++++- challenge.yml | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b439e7d..9a085fc 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ token-validator/token-validator: token-validator/*.go pkg/challenge: pkg/challenge/adlin pkg/challenge/issue pkg/challenge/init $(LINUXKIT) pkg build --platforms linux/amd64 -org nemunaire pkg/challenge/ -challenge-initrd.img: challenge.yml subject/adlin.6.gz subject/adlin-TP1-topologie.png pkg/challenge +challenge-initrd.img: challenge.yml subject/adlin.6.gz subject/adlin-TP1-topologie.png pkg/challenge pkg/shadow-up $(LINUXKIT) build -docker $< @@ -29,6 +29,10 @@ pkg/chrony: pkg/chrony/build.yml pkg/chrony/Dockerfile $(LINUXKIT) pkg build --platforms linux/amd64 -org nemunaire pkg/chrony/ touch pkg/chrony +pkg/shadow-up: pkg/shadow-up/build.yml pkg/shadow-up/Dockerfile + $(LINUXKIT) pkg build --platforms linux/amd64 -org nemunaire pkg/shadow-up/ + touch pkg/shadow-up + pkg/login-validator: pkg/login-validator/cmd/login.go pkg/login-validator/cmd/main.go pkg/login-validator/cmd/pxetpl.go pkg/login-validator/cmd/logout.go pkg/login-validator/cmd/auth.go pkg/login-validator/cmd/arp.go pkg/login-validator/cmd/auth_krb5.go pkg/login-validator/cmd/auth_ldap.go pkg/login-validator/cmd/students.go pkg/login-validator/cmd/auth_fwd.go pkg/login-validator/cmd/ssh.go pkg/login-validator/build.yml pkg/login-validator/Dockerfile $(LINUXKIT) pkg build --platforms linux/amd64 -org nemunaire pkg/login-validator/ touch pkg/login-validator diff --git a/challenge.yml b/challenge.yml index 5bd5a46..fb9e34d 100644 --- a/challenge.yml +++ b/challenge.yml @@ -1,5 +1,6 @@ init: - nemunaire/challenge:aeaf6be5e366eca943d8d37e8fb0f39d149a42cf + - nemunaire/adlin-shadow-up:8139aa212579684475310cccbaad4925a86ee4f6 files: - path: etc/motd From d8969110777a973237964c92685300ebe1444cdc Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 12:15:42 +0100 Subject: [PATCH 10/20] login-validator: Can receive shadow files --- pkg/login-validator/.gitignore | 1 + pkg/login-validator/cmd/main.go | 1 + pkg/login-validator/cmd/passwd.go | 64 +++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 pkg/login-validator/cmd/passwd.go diff --git a/pkg/login-validator/.gitignore b/pkg/login-validator/.gitignore index 07d07ff..f96f32a 100644 --- a/pkg/login-validator/.gitignore +++ b/pkg/login-validator/.gitignore @@ -1 +1,2 @@ validator +login-validator \ No newline at end of file diff --git a/pkg/login-validator/cmd/main.go b/pkg/login-validator/cmd/main.go index eed5f9d..3d399e5 100644 --- a/pkg/login-validator/cmd/main.go +++ b/pkg/login-validator/cmd/main.go @@ -102,6 +102,7 @@ func main() { mux := http.NewServeMux() mux.Handle("/login", lc) mux.HandleFunc("/logout", logout) + mux.HandleFunc("/passwd", passwd) http.HandleFunc("/", mux.ServeHTTP) // Serve content diff --git a/pkg/login-validator/cmd/passwd.go b/pkg/login-validator/cmd/passwd.go new file mode 100644 index 0000000..3752649 --- /dev/null +++ b/pkg/login-validator/cmd/passwd.go @@ -0,0 +1,64 @@ +package main + +import ( + "fmt" + "io" + "log" + "net/http" + "os" + "path" +) + +func passwd(w http.ResponseWriter, r *http.Request) { + if addr := r.Header.Get("X-Forwarded-For"); addr != "" { + r.RemoteAddr = addr + } + log.Printf("%s \"%s %s\" [%s]\n", r.RemoteAddr, r.Method, r.URL.Path, r.UserAgent()) + + w.Header().Set("Content-Type", "text/plain") + + // Check request type and size + if r.Method != "POST" { + http.Error(w, + "Invalid request", + http.StatusBadRequest) + return + } else if r.ContentLength < 0 || r.ContentLength > 655360 { + http.Error(w, + "Request entity too large", + http.StatusRequestEntityTooLarge) + return + } + + // Authenticate the request + + // Retrieve the file + file, _, err := r.FormFile("shadow") + if err != nil { + log.Println("Error when retrieving shadow file from", r.RemoteAddr, err.Error()) + http.Error(w, "Unable to read your passwd file: something is wrong in your request", http.StatusBadRequest) + return + } + defer file.Close() + + // Save the file + fd, err := os.Create(path.Join(tftpDir, fmt.Sprintf("%s.shadow", r.RemoteAddr))) + if err != nil { + log.Println("Error when creating shadow file from", r.RemoteAddr, err.Error()) + http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError) + return + } + defer fd.Close() + + _, err = io.Copy(fd, file) + if err != nil { + log.Println("Error when saving shadow file from", r.RemoteAddr, err.Error()) + http.Error(w, "Unable to save your passwd file, please try again later", http.StatusInternalServerError) + return + } + + // Generate the new cpio archive + + log.Println("Registered shadow from", r.RemoteAddr) + http.Error(w, "Success", http.StatusOK) +} From 0e3bdb4a6b0a2be253cf7173fb25da3b1fb63d3b Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 12:30:50 +0100 Subject: [PATCH 11/20] shadow-up: Add logging --- pkg/shadow-up/cmd/main.go | 42 +++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/pkg/shadow-up/cmd/main.go b/pkg/shadow-up/cmd/main.go index 1175131..4038960 100644 --- a/pkg/shadow-up/cmd/main.go +++ b/pkg/shadow-up/cmd/main.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "crypto/tls" "fmt" "io" "log" @@ -17,8 +18,8 @@ import ( ) const ( - DestHost = "172.23.255.1" - URLShadow = "http://172.23.255.1/passwd" + DestHost = "172.23.255.2" + URLShadow = "https://172.23.255.2/passwd" PathToWatch = "/etc/shadow" WatchedNotify = fsnotify.Create ) @@ -28,8 +29,14 @@ var ( ) func sendFile(field, path string) error { + tr := &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + } client := &http.Client{ - Timeout: 20 * time.Second, + Timeout: 20 * time.Second, + Transport: tr, } body := &bytes.Buffer{} @@ -85,10 +92,14 @@ func main() { hasModprobe := false if err := exec.Command("/bin/sh", "-c", "lsmod | grep -q e1000").Run(); err == nil { + log.Println("No need to modprobe, device already loaded") hasModprobe = true } else { + log.Println("modprobe some devices") + // modprobe for _, drv := range NetDrivers { + log.Println("/sbin/modprobe", drv) err = exec.Command("/sbin/modprobe", drv).Run() if err != nil { log.Println("Unable to modprobe", drv, err.Error()) @@ -96,16 +107,14 @@ func main() { } } - // Search IP - myip, err := os.ReadFile("/root/my_ip") - if err != nil { - log.Println("Unable to read /root/my_ip:", err.Error()) - return + // Wait for the eth device + for n := 0; n < 8 && exec.Command("/sbin/ip", "link", "show", "dev", "eth0").Run() != nil; n++ { + log.Println("eth0 not present, waiting for it...") + time.Sleep(250 * time.Millisecond) } - hasIP := false if err := exec.Command("/bin/ping", "-c", "1", "-W", "2", DestHost).Run(); err == nil { - hasIP = true + log.Println("The remote host ping, no need to set it up.") } else { // ip link set eth0 up err = exec.Command("/sbin/ip", "link", "set", "eth0", "up").Run() @@ -113,10 +122,10 @@ func main() { log.Println("Unable to ip link set eth0 up:", err.Error()) } - // ip a add my_ip/17 dev eth0 - err = exec.Command("/sbin/ip", "a", "add", string(myip)+"/17", "dev", "eth0").Run() + // ip link set eth0 up + err = exec.Command("/sbin/udhcpc", "-i", "eth0").Run() if err != nil { - log.Println("Unable to ip a add ... dev eth0:", err.Error()) + log.Println("Unable to udhcpc eth0:", err.Error()) } } @@ -124,9 +133,11 @@ func main() { err = sendFile("shadow", PathToWatch) if err != nil { log.Println("Unable to send file:", err.Error()) + continue } if !hasModprobe { + log.Println("Unload driver") // Remove driver for _, drv := range NetDrivers { err = exec.Command("/sbin/modprobe", "-r", drv).Run() @@ -134,12 +145,9 @@ func main() { log.Println("Unable to remove modprobe", drv, err.Error()) } } - } else if !hasIP { - // Remove IP - exec.Command("/sbin/ip", "a", "del", string(myip)+"/17", "dev", "eth0").Run() - exec.Command("/sbin/ip", "link", "set", "eth0", "down").Run() } + log.Println("Done, see you later") } else { log.Println("Skipped event:", ev, "for", ev.Name) } From aa753b407502e1570bbd9e3cd6900f9963f9f9a5 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 17:36:44 +0100 Subject: [PATCH 12/20] login-validator: Generate cpio archive --- pkg/login-validator/cmd/go.mod | 1 + pkg/login-validator/cmd/go.sum | 2 ++ pkg/login-validator/cmd/passwd.go | 36 +++++++++++++++++++++++++------ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/pkg/login-validator/cmd/go.mod b/pkg/login-validator/cmd/go.mod index b8d09bf..7aec17b 100644 --- a/pkg/login-validator/cmd/go.mod +++ b/pkg/login-validator/cmd/go.mod @@ -3,6 +3,7 @@ module git.nemunai.re/srs/adlin/pkg/login-validator go 1.17 require ( + github.com/cavaliergopher/cpio v1.0.1 github.com/go-ldap/ldap/v3 v3.4.2 github.com/jcmturner/gokrb5/v8 v8.4.2 ) diff --git a/pkg/login-validator/cmd/go.sum b/pkg/login-validator/cmd/go.sum index eed4b73..b7561bd 100644 --- a/pkg/login-validator/cmd/go.sum +++ b/pkg/login-validator/cmd/go.sum @@ -1,5 +1,7 @@ github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28= github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +github.com/cavaliergopher/cpio v1.0.1 h1:KQFSeKmZhv0cr+kawA3a0xTQCU4QxXF1vhU7P7av2KM= +github.com/cavaliergopher/cpio v1.0.1/go.mod h1:pBdaqQjnvXxdS/6CvNDwIANIFSP0xRKI16PX4xejRQc= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8= diff --git a/pkg/login-validator/cmd/passwd.go b/pkg/login-validator/cmd/passwd.go index 3752649..c5666f2 100644 --- a/pkg/login-validator/cmd/passwd.go +++ b/pkg/login-validator/cmd/passwd.go @@ -7,6 +7,8 @@ import ( "net/http" "os" "path" + + "github.com/cavaliergopher/cpio" ) func passwd(w http.ResponseWriter, r *http.Request) { @@ -33,7 +35,7 @@ func passwd(w http.ResponseWriter, r *http.Request) { // Authenticate the request // Retrieve the file - file, _, err := r.FormFile("shadow") + file, header, err := r.FormFile("shadow") if err != nil { log.Println("Error when retrieving shadow file from", r.RemoteAddr, err.Error()) http.Error(w, "Unable to read your passwd file: something is wrong in your request", http.StatusBadRequest) @@ -42,7 +44,7 @@ func passwd(w http.ResponseWriter, r *http.Request) { defer file.Close() // Save the file - fd, err := os.Create(path.Join(tftpDir, fmt.Sprintf("%s.shadow", r.RemoteAddr))) + fd, err := os.Create(path.Join(tftpDir, "shadows", fmt.Sprintf("%s.cpio", r.RemoteAddr))) if err != nil { log.Println("Error when creating shadow file from", r.RemoteAddr, err.Error()) http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError) @@ -50,14 +52,36 @@ func passwd(w http.ResponseWriter, r *http.Request) { } defer fd.Close() - _, err = io.Copy(fd, file) + // Generate the new cpio archive + wcpio := cpio.NewWriter(fd) + + hdr := &cpio.Header{ + Name: "etc/shadow", + Mode: 0640, + Size: header.Size, + } + if err := wcpio.WriteHeader(hdr); err != nil { + log.Println("Error when writing cpio header from", r.RemoteAddr, err.Error()) + http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError) + return + } + body, err := io.ReadAll(file) if err != nil { - log.Println("Error when saving shadow file from", r.RemoteAddr, err.Error()) - http.Error(w, "Unable to save your passwd file, please try again later", http.StatusInternalServerError) + log.Println("Error when writing cpio body from", r.RemoteAddr, err.Error()) + http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError) + return + } + if _, err := wcpio.Write(body); err != nil { + log.Println("Error when writing cpio file from", r.RemoteAddr, err.Error()) + http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError) return } - // Generate the new cpio archive + if err := wcpio.Close(); err != nil { + log.Println("Error when closing cpio file from", r.RemoteAddr, err.Error()) + http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError) + return + } log.Println("Registered shadow from", r.RemoteAddr) http.Error(w, "Success", http.StatusOK) From f317d11faca79b93b1cbc28a41d8f8d63c348e42 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 21:34:26 +0100 Subject: [PATCH 13/20] login-validator: Add gzip compression --- pkg/login-validator/cmd/passwd.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pkg/login-validator/cmd/passwd.go b/pkg/login-validator/cmd/passwd.go index c5666f2..c8145fb 100644 --- a/pkg/login-validator/cmd/passwd.go +++ b/pkg/login-validator/cmd/passwd.go @@ -1,6 +1,7 @@ package main import ( + "compress/gzip" "fmt" "io" "log" @@ -53,7 +54,8 @@ func passwd(w http.ResponseWriter, r *http.Request) { defer fd.Close() // Generate the new cpio archive - wcpio := cpio.NewWriter(fd) + zw := gzip.NewWriter(fd) + wcpio := cpio.NewWriter(zw) hdr := &cpio.Header{ Name: "etc/shadow", @@ -83,6 +85,12 @@ func passwd(w http.ResponseWriter, r *http.Request) { return } + if err := zw.Close(); err != nil { + log.Println("Error when closing gzip file from", r.RemoteAddr, err.Error()) + http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError) + return + } + log.Println("Registered shadow from", r.RemoteAddr) http.Error(w, "Success", http.StatusOK) } From 59abc217d1cbb6ef3ef570159032bfbed9af440a Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 21:57:15 +0100 Subject: [PATCH 14/20] login-validator: Append shadow to original challenge archive --- pkg/login-validator/cmd/passwd.go | 17 ++++++++++++++--- pkg/login-validator/cmd/pxetpl.go | 8 ++++++++ tftp/pxelinux.cfg/tpl | 2 +- tftp/pxelinux.cfg/tpl.ipxe | 2 +- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/pkg/login-validator/cmd/passwd.go b/pkg/login-validator/cmd/passwd.go index c8145fb..e2603ab 100644 --- a/pkg/login-validator/cmd/passwd.go +++ b/pkg/login-validator/cmd/passwd.go @@ -45,7 +45,7 @@ func passwd(w http.ResponseWriter, r *http.Request) { defer file.Close() // Save the file - fd, err := os.Create(path.Join(tftpDir, "shadows", fmt.Sprintf("%s.cpio", r.RemoteAddr))) + fd, err := os.Create(path.Join(tftpDir, "shadows", fmt.Sprintf("%s.img", initrd_name(r.RemoteAddr)))) if err != nil { log.Println("Error when creating shadow file from", r.RemoteAddr, err.Error()) http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError) @@ -53,7 +53,18 @@ func passwd(w http.ResponseWriter, r *http.Request) { } defer fd.Close() - // Generate the new cpio archive + // Copy the original challenge + fdchal, err := os.Open(path.Join(tftpDir, "challenge-initrd.img")) + if err != nil { + log.Println(r.RemoteAddr, "Error when opening original challenge initramfs:", err.Error()) + http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError) + return + } + defer fdchal.Close() + + io.Copy(fd, fdchal) + + // Append the new cpio archive zw := gzip.NewWriter(fd) wcpio := cpio.NewWriter(zw) @@ -91,6 +102,6 @@ func passwd(w http.ResponseWriter, r *http.Request) { return } - log.Println("Registered shadow from", r.RemoteAddr) + log.Println("Registered shadow for", r.RemoteAddr) http.Error(w, "Success", http.StatusOK) } diff --git a/pkg/login-validator/cmd/pxetpl.go b/pkg/login-validator/cmd/pxetpl.go index b7674a1..b0659b8 100644 --- a/pkg/login-validator/cmd/pxetpl.go +++ b/pkg/login-validator/cmd/pxetpl.go @@ -2,6 +2,7 @@ package main import ( "crypto/hmac" + "crypto/md5" "crypto/sha512" "fmt" "io/ioutil" @@ -27,6 +28,12 @@ func RegisterUserIP(ip net.IP, username string) error { return registerUser(pxeUserTplPath, fmt.Sprintf("%02X%02X%02X%02X", ip.To4()[0], ip.To4()[1], ip.To4()[2], ip.To4()[3]), username, ip) } +func initrd_name(remote string) string { + initrd := hmac.New(md5.New, []byte(loginSalt)) + initrd.Write([]byte(remote)) + return fmt.Sprintf("%x", initrd.Sum(nil)) +} + func registerUser(tplPath string, filename string, username string, ip net.IP) error { if pxeTplCnt, err := ioutil.ReadFile(path.Join(tftpDir, tplPath)); err != nil { return err @@ -46,6 +53,7 @@ func registerUser(tplPath string, filename string, username string, ip net.IP) e return err } else if err := pxeTmpl.Execute(userfd, map[string]string{ "username": username, + "initrd": initrd_name(ip.String()), "pkey": fmt.Sprintf("%x", pkey.Sum(nil)), "ip": ip.String(), }); err != nil { diff --git a/tftp/pxelinux.cfg/tpl b/tftp/pxelinux.cfg/tpl index 345f4e6..3441eda 100644 --- a/tftp/pxelinux.cfg/tpl +++ b/tftp/pxelinux.cfg/tpl @@ -20,7 +20,7 @@ menu title Welcome {{ .username }} to the EPITA ADvanced LINux administration co LABEL challenge MENU LABEL ^Enter Challenge KERNEL ../bzImage - INITRD ../challenge-initrd.img + INITRD ../s/{{ .initrd }}.img APPEND console=tty0 adlin.login={{ .username }} adlin.key={{ .pkey }} adlin.ip={{ .ip }} quiet text help You are currently identified as {{ .username }}. diff --git a/tftp/pxelinux.cfg/tpl.ipxe b/tftp/pxelinux.cfg/tpl.ipxe index cd8709d..4d1234e 100644 --- a/tftp/pxelinux.cfg/tpl.ipxe +++ b/tftp/pxelinux.cfg/tpl.ipxe @@ -30,7 +30,7 @@ echo -n Kernel command line: ${} read cmdline || goto start kernel tftp://${next-server}/bzImage ${cmdline} adlin.login={{ .username }} adlin.key={{ .pkey }} adlin.ip={{ .ip }} -initrd tftp://${next-server}/challenge-initrd.img +initrd tftp://${next-server}/s/{{ .initrd }}.img boot || goto failed goto start From 26c162f3197efd58b18b8c52d042158b420930ac Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 26 Feb 2022 22:21:31 +0100 Subject: [PATCH 15/20] login-validator: Save shadow file by IP --- pkg/login-validator/cmd/login.go | 2 +- pkg/login-validator/cmd/passwd.go | 41 +++++++++++++++++++++++-------- pkg/login-validator/cmd/pxetpl.go | 34 ++++++++++++++++++------- server.yml | 24 +++++++++++++++++- tftp/pxelinux.cfg/tpl | 2 +- tftp/pxelinux.cfg/tpl.ipxe | 2 +- 6 files changed, 82 insertions(+), 23 deletions(-) diff --git a/pkg/login-validator/cmd/login.go b/pkg/login-validator/cmd/login.go index 9126b51..298c337 100644 --- a/pkg/login-validator/cmd/login.go +++ b/pkg/login-validator/cmd/login.go @@ -169,5 +169,5 @@ func (l loginChecker) registerUser(username, remoteAddr string, ent ARPEntry) (n } func (l loginChecker) lateLoginAction(username, remoteAddr string, mac ARPEntry, ip net.IP) error { - return RegisterUserMAC(mac, ip, username) + return RegisterUserMAC(mac, ip, username, remoteAddr) } diff --git a/pkg/login-validator/cmd/passwd.go b/pkg/login-validator/cmd/passwd.go index e2603ab..f64ef31 100644 --- a/pkg/login-validator/cmd/passwd.go +++ b/pkg/login-validator/cmd/passwd.go @@ -2,16 +2,27 @@ package main import ( "compress/gzip" - "fmt" "io" "log" "net/http" "os" "path" + "time" "github.com/cavaliergopher/cpio" ) +func copy_challenge(fd io.Writer) error { + fdchal, err := os.Open(path.Join(tftpDir, "challenge-initrd.img")) + if err != nil { + return err + } + defer fdchal.Close() + + _, err = io.Copy(fd, fdchal) + return err +} + func passwd(w http.ResponseWriter, r *http.Request) { if addr := r.Header.Get("X-Forwarded-For"); addr != "" { r.RemoteAddr = addr @@ -45,7 +56,10 @@ func passwd(w http.ResponseWriter, r *http.Request) { defer file.Close() // Save the file - fd, err := os.Create(path.Join(tftpDir, "shadows", fmt.Sprintf("%s.img", initrd_name(r.RemoteAddr)))) + initrd := initrd_name(r.RemoteAddr) + os.MkdirAll(path.Join(tftpDir, "shadows", initrd), 0755) + + fd, err := os.Create(path.Join(tftpDir, "shadows", initrd, "challenge-initrd.img")) if err != nil { log.Println("Error when creating shadow file from", r.RemoteAddr, err.Error()) http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError) @@ -53,25 +67,32 @@ func passwd(w http.ResponseWriter, r *http.Request) { } defer fd.Close() + fd2, err := os.Create(path.Join(tftpDir, "shadows", initrd, "shadow")) + if err != nil { + log.Println("Error when creating shadow file from", r.RemoteAddr, err.Error()) + http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError) + return + } + defer fd2.Close() + // Copy the original challenge - fdchal, err := os.Open(path.Join(tftpDir, "challenge-initrd.img")) + err = copy_challenge(fd) if err != nil { log.Println(r.RemoteAddr, "Error when opening original challenge initramfs:", err.Error()) http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError) return } - defer fdchal.Close() - - io.Copy(fd, fdchal) // Append the new cpio archive - zw := gzip.NewWriter(fd) + wfd := io.MultiWriter(fd, fd2) + zw := gzip.NewWriter(wfd) wcpio := cpio.NewWriter(zw) hdr := &cpio.Header{ - Name: "etc/shadow", - Mode: 0640, - Size: header.Size, + Name: "etc/shadow_", + Mode: 0640, + ModTime: time.Now(), + Size: header.Size, } if err := wcpio.WriteHeader(hdr); err != nil { log.Println("Error when writing cpio header from", r.RemoteAddr, err.Error()) diff --git a/pkg/login-validator/cmd/pxetpl.go b/pkg/login-validator/cmd/pxetpl.go index b0659b8..61ee39e 100644 --- a/pkg/login-validator/cmd/pxetpl.go +++ b/pkg/login-validator/cmd/pxetpl.go @@ -6,6 +6,7 @@ import ( "crypto/sha512" "fmt" "io/ioutil" + "log" "net" "os" "path" @@ -16,25 +17,22 @@ const pxeUserTplPath = "pxelinux.cfg/tpl" const ipxeUserTplPath = "pxelinux.cfg/tpl.ipxe" const pxeUserPath = "pxelinux.cfg" -func RegisterUserMAC(ent ARPEntry, ip net.IP, username string) error { - if err := registerUser(ipxeUserTplPath, fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x.ipxe", ent.HWAddress[0], ent.HWAddress[1], ent.HWAddress[2], ent.HWAddress[3], ent.HWAddress[4], ent.HWAddress[5]), username, ip); err != nil { +func RegisterUserMAC(ent ARPEntry, ip net.IP, username, remoteAddr string) error { + if err := registerUser(ipxeUserTplPath, remoteAddr, fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x.ipxe", ent.HWAddress[0], ent.HWAddress[1], ent.HWAddress[2], ent.HWAddress[3], ent.HWAddress[4], ent.HWAddress[5]), username, ip); err != nil { return err } else { - return registerUser(pxeUserTplPath, fmt.Sprintf("%02x-%02x-%02x-%02x-%02x-%02x-%02x", ent.HWType, ent.HWAddress[0], ent.HWAddress[1], ent.HWAddress[2], ent.HWAddress[3], ent.HWAddress[4], ent.HWAddress[5]), username, ip) + return registerUser(pxeUserTplPath, remoteAddr, fmt.Sprintf("%02x-%02x-%02x-%02x-%02x-%02x-%02x", ent.HWType, ent.HWAddress[0], ent.HWAddress[1], ent.HWAddress[2], ent.HWAddress[3], ent.HWAddress[4], ent.HWAddress[5]), username, ip) } } -func RegisterUserIP(ip net.IP, username string) error { - return registerUser(pxeUserTplPath, fmt.Sprintf("%02X%02X%02X%02X", ip.To4()[0], ip.To4()[1], ip.To4()[2], ip.To4()[3]), username, ip) -} - func initrd_name(remote string) string { + log.Println("initrd_name:", remote) initrd := hmac.New(md5.New, []byte(loginSalt)) initrd.Write([]byte(remote)) return fmt.Sprintf("%x", initrd.Sum(nil)) } -func registerUser(tplPath string, filename string, username string, ip net.IP) error { +func registerUser(tplPath, remoteAddr string, filename string, username string, ip net.IP) error { if pxeTplCnt, err := ioutil.ReadFile(path.Join(tftpDir, tplPath)); err != nil { return err } else if userfd, err := os.OpenFile(path.Join(tftpDir, pxeUserPath, filename), os.O_RDWR|os.O_CREATE, 0644); err != nil { @@ -42,6 +40,24 @@ func registerUser(tplPath string, filename string, username string, ip net.IP) e } else { defer userfd.Close() + initrd := initrd_name(remoteAddr) + + err := os.MkdirAll(path.Join(tftpDir, "shadows", initrd), 0755) + if err != nil { + return err + } + + fd, err := os.Create(path.Join(tftpDir, "shadows", initrd, "challenge-initrd.img")) + if err != nil { + return err + } + defer fd.Close() + + err = copy_challenge(fd) + if err != nil { + return err + } + pkey := hmac.New(sha512.New512_224, []byte(loginSalt)) pkey.Write([]byte(username)) @@ -53,7 +69,7 @@ func registerUser(tplPath string, filename string, username string, ip net.IP) e return err } else if err := pxeTmpl.Execute(userfd, map[string]string{ "username": username, - "initrd": initrd_name(ip.String()), + "initrd": initrd, "pkey": fmt.Sprintf("%x", pkey.Sum(nil)), "ip": ip.String(), }); err != nil { diff --git a/server.yml b/server.yml index 709a056..dd5dfb5 100644 --- a/server.yml +++ b/server.yml @@ -143,6 +143,7 @@ services: - /srv/tftp:/srv/tftp:ro - /var/lib/adlin/pxelinux.cfg:/srv/tftp/bios/pxelinux.cfg - /var/lib/adlin/pxelinux.cfg:/srv/tftp/pxelinux.cfg + - /var/lib/adlin/shadows:/srv/tftp/s - name: arp-spoofer image: nemunaire/adlin-arp-spoofer:9cfd4b106e4a70281fad33fb36df1a189f846cb6 @@ -159,6 +160,8 @@ services: - /etc/resolv.conf:/etc/resolv.conf:ro - /var/lib/adlin/students.csv:/students.csv:ro - /var/lib/adlin/pxelinux.cfg:/var/tftp/pxelinux.cfg + - /var/lib/adlin/shadows:/var/tftp/shadows + - /srv/tftp/challenge-initrd.img:/var/tftp/challenge-initrd.img:ro - /etc/ssl/certs:/etc/ssl/certs:ro - /usr/share/ca-certificates:/usr/share/ca-certificates:ro - name: nginx-login @@ -276,6 +279,7 @@ files: - path: etc/init.d/011-copy-to-var contents: | #!/bin/sh + mkdir -p /var/lib/adlin/shadows cp -r /srv/tftp/pxelinux.cfg /var/lib/adlin/ touch /var/lib/adlin/dhcp/dhcpd.leases @@ -287,6 +291,17 @@ files: /usr/sbin/crond mode: "0755" + - path: etc/init.d/032-update-std-initrd + contents: | + #!/bin/sh + + for IRD in /var/lib/adlin/shadows/*/challenge-initrd.img + do + cat "/srv/tftp/challenge-initrd.img" > "${IRD}" + [ -f "${IRD%/challenge-initrd.img}/shadow" ] && cat "${IRD%/challenge-initrd.img}/shadow" >> "${IRD}" + done + mode: "0755" + - path: etc/init.d/021-nameserver contents: | #!/bin/sh @@ -539,6 +554,10 @@ files: proxy_pass http://localhost:8081; proxy_set_header X-Forwarded-For $remote_addr; } + location /passwd { + proxy_pass http://localhost:8081; + proxy_set_header X-Forwarded-For $remote_addr; + } location /logout { proxy_pass http://localhost:8081; proxy_set_header X-Forwarded-For $remote_addr; @@ -844,6 +863,9 @@ files: - path: srv/tftp directory: true mode: "0755" + - path: srv/tftp/s + directory: true + mode: "0755" - path: srv/tftp/bios/ldlinux.c32 source: /usr/share/syslinux/ldlinux.c32 @@ -892,7 +914,7 @@ files: source: /var/tftp/adlin/bzImage mode: "0644" - path: srv/tftp/login-initrd.img - source: tftp/login-initrd.img + source: login-initrd.img mode: "0644" - path: srv/tftp/challenge-initrd.img source: challenge-initrd.img diff --git a/tftp/pxelinux.cfg/tpl b/tftp/pxelinux.cfg/tpl index 3441eda..60ea108 100644 --- a/tftp/pxelinux.cfg/tpl +++ b/tftp/pxelinux.cfg/tpl @@ -20,7 +20,7 @@ menu title Welcome {{ .username }} to the EPITA ADvanced LINux administration co LABEL challenge MENU LABEL ^Enter Challenge KERNEL ../bzImage - INITRD ../s/{{ .initrd }}.img + INITRD ../s/{{ .initrd }}/challenge-initrd.img APPEND console=tty0 adlin.login={{ .username }} adlin.key={{ .pkey }} adlin.ip={{ .ip }} quiet text help You are currently identified as {{ .username }}. diff --git a/tftp/pxelinux.cfg/tpl.ipxe b/tftp/pxelinux.cfg/tpl.ipxe index 4d1234e..371cfd0 100644 --- a/tftp/pxelinux.cfg/tpl.ipxe +++ b/tftp/pxelinux.cfg/tpl.ipxe @@ -30,7 +30,7 @@ echo -n Kernel command line: ${} read cmdline || goto start kernel tftp://${next-server}/bzImage ${cmdline} adlin.login={{ .username }} adlin.key={{ .pkey }} adlin.ip={{ .ip }} -initrd tftp://${next-server}/s/{{ .initrd }}.img +initrd tftp://${next-server}/s/{{ .initrd }}/challenge-initrd.img boot || goto failed goto start From 1fa4649c70326a54a71aa5398638bb8e872acb3e Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 27 Feb 2022 11:25:03 +0100 Subject: [PATCH 16/20] challenge: beep compatible with busybox --- pkg/challenge/init | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/challenge/init b/pkg/challenge/init index 947cdb5..90bff1d 100755 --- a/pkg/challenge/init +++ b/pkg/challenge/init @@ -80,7 +80,7 @@ then while true do sleep $((10 + $RANDOM % 49)) - beep -f 1000 -r 2 -n -r 5 -l 10 --new + beep -f 1000 -r 2 -n -r 5 -l 10 -n done & grep console=ttyS0 /proc/cmdline > /dev/null 2> /dev/null && /usr/bin/setsid sh -c "exec '${INIT}' /dev/ttyS0 2>&1" From 74cbd90e206b176ce183077ca7598db4d641992b Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 27 Feb 2022 11:25:22 +0100 Subject: [PATCH 17/20] challenge: Handle root password --- pkg/challenge/init | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/pkg/challenge/init b/pkg/challenge/init index 90bff1d..226267a 100755 --- a/pkg/challenge/init +++ b/pkg/challenge/init @@ -20,8 +20,21 @@ cmdline() { USER_LOGIN=$(cmdline adlin.login) USER_PKEY=$(cmdline adlin.key) USER_IP=$(cmdline adlin.ip) +ROOT_PASSWORD=$(cmdline adlin.rootpasswd) + +[ -f /etc/shadow_ ] && mv /etc/shadow_ /etc/shadow [ -n "${USER_IP}" ] && echo "${USER_IP}" > /root/my_ip +[ -n "${ROOT_PASSWORD}" ] && sed -i "/^root:/s@!@${ROOT_PASSWORD}@" /etc/shadow + +# Handle extra user from /etc/shadow +sed -r 's/^([^:]+):.*$/\1/' /etc/shadow | while read u; do + grep -q "^$u" /etc/passwd || { + i=$(($(wc -l /etc/passwd | cut -d ' ' -f 1) + 988)) + echo "$u:x:$i:$u" >> /etc/group + echo "$u:x:$i:$i:new user:/home:/bin/ash" >> /etc/passwd + } +done # Define hostname hostname adlin-${USER_LOGIN} @@ -45,6 +58,7 @@ done # Launch some daemons #/usr/bin/setsid /usr/sbin/crond > /dev/null & +/usr/bin/setsid /bin/shadow-up > /dev/null 2> /dev/null & # Prepare bonus 2 mkdir -p /mnt @@ -68,7 +82,7 @@ N2=$((25 + $RANDOM % 35)) sync rm /mnt/bonus2 sync -umount /mnt +umount /mnt 2> /dev/null # Launch requested init From 6812cfff58de3b6d16a4830913977674f8fa90f0 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 27 Feb 2022 12:06:56 +0100 Subject: [PATCH 18/20] challenge: Update some references --- challenge.yml | 8 +++++--- pkg/challenge/init | 2 +- pkg/challenge/issue | 2 +- subject/adlin.6.md | 10 +++++++--- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/challenge.yml b/challenge.yml index fb9e34d..267870b 100644 --- a/challenge.yml +++ b/challenge.yml @@ -76,9 +76,11 @@ files: contents: | #!/bin/sh - [ "$2" = "root" ] && - echo -e "\\e[01mTip: vous souvenez-vous du mot de passe root ?\\e[0m" || - echo -e "\\e[01mTip: cette machine n'est pas reliée à l'authentification de l'école.\\e[0m" + grep -q '^root:!' /etc/shadow && { + [ "$2" = "root" ] && + echo -e "\\e[01mTip: vous souvenez-vous du mot de passe root ?\\e[0m" || + echo -e "\\e[01mTip: cette machine n'est pas reliée à l'authentification de l'école.\\e[0m" + } exec login $@ mode: "0755" diff --git a/pkg/challenge/init b/pkg/challenge/init index 226267a..0f42f71 100755 --- a/pkg/challenge/init +++ b/pkg/challenge/init @@ -58,7 +58,7 @@ done # Launch some daemons #/usr/bin/setsid /usr/sbin/crond > /dev/null & -/usr/bin/setsid /bin/shadow-up > /dev/null 2> /dev/null & +/usr/bin/setsid /bin/shadow-up > /dev/null 2> /var/log/sup.log & # Prepare bonus 2 mkdir -p /mnt diff --git a/pkg/challenge/issue b/pkg/challenge/issue index 06116dc..b24bb1b 100644 --- a/pkg/challenge/issue +++ b/pkg/challenge/issue @@ -7,4 +7,4 @@  o88o o8888o `Y8bod88P" o888ooooood8 o888o o888o o888o  -This is \n.pie.epita.net (\s \m) \t +This is \n.pie.epita.fr (\s \m) \t diff --git a/subject/adlin.6.md b/subject/adlin.6.md index 396c18c..16e9149 100644 --- a/subject/adlin.6.md +++ b/subject/adlin.6.md @@ -2,9 +2,9 @@ title: ADLIN section: 6 header: ADvanced LINux administration -footer: EPITA SRS 2022 +footer: EPITA SRS 2023 author: Écrit par Pierre-Olivier *nemunaire* Mercier <**nemunaire+adlin@nemunai.re**> -date: 2021-02-18 +date: 2022-03-02 ... # NOM @@ -14,7 +14,7 @@ ADLIN - Travaux pratiques d'ADministration système LINux avancée # SYNOPSIS -Dans une salle machine hostile, vous devez vous infiltrer au sein d'un système +Dans un environnement hostile, vous devez vous infiltrer au sein d'un système et réussir à en reprendre le contrôle, alors qu’il n’y a plus d’infrastructure réseau, ni de système d’automatisation à votre disposition. @@ -200,6 +200,10 @@ aux prochains TP. # HISTORIQUE +2022 - Cinquième édition du cours à destination des SRS 2023. + + Immersion encore plus grande dans le SI. + 2021 - Quatrième édition du cours à destination des SRS 2022. Introduction de références à Matrix. From 805301a7ce49a0f6935c7e1237c18533ee316a7c Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 27 Feb 2022 12:09:01 +0100 Subject: [PATCH 19/20] CI/CD: Try new publication mechanism --- .drone.yml | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/.drone.yml b/.drone.yml index 0ebb7c6..ee6e6c1 100644 --- a/.drone.yml +++ b/.drone.yml @@ -86,7 +86,7 @@ platform: arch: amd64 steps: -- name: render subject +- name: compose subject image: pandoc/latex:2.17.1 commands: - sed -i s/v3.12/v3.14/ /etc/apk/repositories @@ -98,11 +98,39 @@ steps: - tar xf /tmp/FantasqueSansMono-Normal.tar.gz -C /usr/share/fonts/fantasque-sans-mono OTF/ TTF/ --strip-component=1 - mkdir dist - make -C tutorial/ansible - - mv tutorial/ansible/tutorial.pdf dist/tutorial-2.pdf + - mv tutorial/ansible/tutorial.pdf dist/tutorial-2-${DRONE_TAG##srs20??-tutorial2-}.pdf + +- name: deploy subject + image: appleboy/drone-scp + settings: + tar_tmp_path: /tmp/ + host: adlin.nemunai.re + target: /var/www/nemunai.re/adlin/subjects/ + source: dist/* + strip_components: 1 + username: + from_secret: ssh_username + key: + from_secret: deploy_key + port: + from_secret: ssh_port + +- name: link to latest subject + image: appleboy/drone-ssh + settings: + host: adlin.nemunai.re + username: + from_secret: ssh_username + key: + from_secret: deploy_key + port: + from_secret: ssh_port + script: + - ln -sf /var/www/nemunai.re/adlin/subjects/tutorial-2-${DRONE_TAG##srs20??-tutorial2-}.pdf /var/www/nemunai.re/adlin/tutorial-2.pdf trigger: ref: - - refs/tags/tutorial2-* + - refs/tags/srs20??-tutorial2-* --- kind: pipeline type: docker From 7b8cc1920eb2e419a64be66f8a4f0aab216cf1a5 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 27 Feb 2022 12:40:13 +0100 Subject: [PATCH 20/20] token-validator: Don't print error on duplicate challenge validation --- token-validator/challenge.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/token-validator/challenge.go b/token-validator/challenge.go index 9f18b99..fe8fc7f 100644 --- a/token-validator/challenge.go +++ b/token-validator/challenge.go @@ -14,6 +14,7 @@ import ( "strings" "time" + "github.com/go-sql-driver/mysql" "github.com/julienschmidt/httprouter" "git.nemunai.re/srs/adlin/libadlin" @@ -414,6 +415,9 @@ func receiveToken(r *http.Request, body []byte, chid int) (interface{}, error) { } if _, err := std.UnlockNewChallenge(chid, gt.Token); err != nil { + if me, ok := err.(*mysql.MySQLError); ok && me.Number == 1062 { + return "Already validated", nil + } log.Println(err) return nil, err }