Compare commits

...

93 Commits

Author SHA1 Message Date
9bbfef4c39
compose: use docker compose, not docker-compose
All checks were successful
continuous-integration/drone/push Build is passing
* get on with the times...plus the old form does not like the compose
  file anymore
* also add an empty volume to make compose happy
2024-05-28 22:45:53 +02:00
b796f72abc
go: add a 404 handler
All checks were successful
continuous-integration/drone/push Build is passing
2024-04-02 23:32:51 +02:00
22e4b4d5a4
add info on DOH to the services page
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-05 15:15:31 +02:00
7fbdfac786
md: update contact info
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-25 23:32:48 +03:00
131e84bd17
ci,dockerfile: bump to go1.21
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-13 16:03:13 +02:00
2906fb1b88
chore: add todos [skip ci] 2023-08-13 16:00:27 +02:00
e9bd63decb
pre-commit-config: update hugo check [skip ci] 2023-07-29 17:06:39 +02:00
9c6215d9a1
chore: bump hugo to v0.115.3
All checks were successful
continuous-integration/drone/push Build is passing
the hugo bump required updating some configuration fields, those are
thus part of this change set
2023-07-20 16:21:41 +02:00
aa539af15d
add .golangci.yml
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-19 22:43:44 +02:00
3dbafe08e7
ci,dockerfile,gomod: bump base to go1.20
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-19 22:39:12 +02:00
d081a79f6d
go: add server read/write timeouts
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-19 22:35:42 +02:00
419686eb0c
chore(dockerfile): bump docker preamble
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-19 22:27:48 +02:00
leo
aa2b945765
posts: add m32.md
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
2023-06-14 14:14:25 +02:00
leo
e49b97a80a
partials: add width,height to gitea svg
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-20 21:25:44 +01:00
leo
07b479d3bf
revert 3a6fe46 adding incorrect meta tag
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-14 15:40:21 +01:00
leo
9ec1a876d1
chore: add 28bd2388 page's description
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-14 15:30:13 +01:00
leo
2a8ef46357
chore: add onions page's description
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-14 15:28:06 +01:00
leo
a3a5a19710
chore: add privacy page's description
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-14 15:26:29 +01:00
leo
cf1a632e3e
chore: add contact page's description
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-14 15:24:32 +01:00
leo
d8e801a178
chore: add about page's description
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-14 15:23:54 +01:00
leo
df3d9c644f
chore: add services description
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-14 15:21:22 +01:00
leo
fb351a2e8d
chore: add post description
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-14 15:18:27 +01:00
leo
ad9a9e679f
compose: comment out internal-nw
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-14 14:50:33 +01:00
leo
3a6fe46e26
add alternative meta description to baseof.html
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-14 14:39:07 +01:00
leo
6928c45106
add aria role to footer tmpl
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-14 14:27:49 +01:00
leo
057ca6edba
add aria role to homepage footer
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-14 14:24:09 +01:00
leo
3020a43ca2
hotfix: disable traefik, scale down homepage
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-31 01:21:02 +01:00
leo
3b36350faf
compose: adapt to changed socket location
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-30 17:22:11 +01:00
leo
759d7a1ccb
dockerfile: bump go base img to :1.18.9-alpine3.17
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-16 17:19:35 +01:00
leo
c4bea59899
compose: bump traefik to 2.9.6
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-16 16:47:37 +01:00
leo
f680d0cefa
compose: bump traefik to 2.9.5
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-16 16:18:05 +01:00
e29cf10b03
readme: make title link to repo
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-31 15:22:14 +01:00
b720c1224b
chore(ci,dockerfile): bump hugo to v0.105.0
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-28 23:32:35 +02:00
44ae248e72
compose: bump traefik to 2.9.4
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-28 23:20:58 +02:00
698f3f0329
compose: bump traefik to 2.9.1
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-11 17:20:08 +02:00
fe2aba1e74
compose: bump traefik to 2.8.8
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-11 17:18:02 +02:00
5c258c0b8b
chore(ci,dockerfile): bump hugo to v0.104.1
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-28 16:02:48 +02:00
f47d06eded
bump traefik to 2.8.7
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-28 15:59:03 +02:00
6e25befe64
pre-commit: add hugo-version-check hook
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-28 15:55:50 +02:00
b023e6bcba
chore(ci,dockerfile): bump hugo to v0.103.0
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-17 13:18:43 +02:00
bbe295aea9
bump traefik to 2.8.5
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-17 03:44:21 +02:00
df4791a3b1
content: add age key, split contact page
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
2022-09-12 17:30:18 +02:00
f363952d13
ci(compose): split long cmd to multiple lines
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-09 14:47:09 +02:00
9b08a69426
ci: add 'check compose' step to pipelines
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-09 14:37:37 +02:00
4912d1f9e8
compose: add healthcheck
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-09 13:21:44 +02:00
3b9343debf
chore(compose,ci): always specify registry
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-09 12:56:04 +02:00
fab63e3eee
bump traefik to 2.8.4
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-09 12:23:37 +02:00
7a178b29af
content: add (affiliate) link to UptimeRobot
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-06 16:11:32 +02:00
937621ae7e
ci(fix): use correct tag (broken by c88a02c)
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
additionally, show hugo version on pull
2022-09-04 20:30:05 +02:00
f36a545c93
config: format datetime according to RFC1123Z
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-01 20:17:21 +02:00
20b3218aab
layouts(posts): add lastmod if set
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-01 03:08:03 +02:00
87138d7b1e
content(dnscrypt): add tips, reword, reformat
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-01 02:36:58 +02:00
c88a02c101
chore: bump hugo to v0.102.2
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-01 01:42:11 +02:00
04eeda81c7
ci: start signing .drone.yml
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-01 01:36:06 +02:00
8afe3e0524
chore: bump hugo to v0.102.1
All checks were successful
continuous-integration/drone/push Build is passing
2022-09-01 01:19:15 +02:00
6e1039893d
ci,dockerfile: switch to immawanderer/alpine-hugo
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-31 21:46:29 +02:00
051903761c
content: add privacy.md, update {about,contact}.md
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-30 13:03:36 +02:00
f7d9892205
content: add {services,onions}.md, update about.md
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-30 12:43:55 +02:00
e358a0d1a4
archetypes: set git info by default [skip ci] 2022-08-30 11:50:25 +02:00
bf16d9d763
archetypes: set lastmod by default [skip ci] 2022-08-30 11:50:02 +02:00
90aca411aa
content(about): add note on CoreDNS DoT resolver
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-30 11:35:37 +02:00
31ea1683aa
ignore binary [skip ci] 2022-08-28 17:36:44 +02:00
6923776886
content(dnscrypt): partially reword the post
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-28 17:29:07 +02:00
bcd6f3bf1a
ci: unify GOFLAGS with dockerfile
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-23 13:36:45 +02:00
26bc3d7d61
enable pygments to use classes
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-21 18:01:42 +02:00
084258ee6c
content(about): add note on SearXNG
All checks were successful
continuous-integration/drone/push Build is passing
instance deployed at https://searxng.dotya.ml
2022-08-21 17:30:05 +02:00
b0dc51e14c
content(about): add note on tmate
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-21 17:27:57 +02:00
e20bf87831
bump traefik to 2.8.3
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-14 11:48:20 +02:00
c68a84082f
bump traefik to 2.8.2
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-12 21:36:28 +02:00
c9553bf7e5
ci: add 'VCS_REF' build arg during compose build
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-08 16:51:03 +02:00
35b2cd330c
readme: add pre-commit badge [skip ci] 2022-08-08 16:50:31 +02:00
9ae12826a8
dockerfile: migrate to docker frontend v1.3
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-08 16:47:39 +02:00
5df1659c6f
pre-commit: add hadonlint-container hook [skip ci] 2022-08-08 16:46:52 +02:00
a894b9eff5
ci: bump hadolint to v2.10.0-alpine
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-08 16:35:20 +02:00
e314f788e7
content(about): add mention of cryptcheck.fr scans
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-08 16:28:11 +02:00
c3a29bef55
fix: {ci race condition,traefik}
All checks were successful
continuous-integration/drone/push Build is passing
as a result of #33:
* traefik proxy according to compose was pointing nowhere
* traefik was attempting to redirect as it used to when the site was
  behind nginx, which is unneccessary now, the go app can properly
  handle paths such as '/tags/'.
2022-08-08 15:27:27 +02:00
cfe496dcb7
embed homepage in a Go app (#33)
Some checks failed
continuous-integration/drone/push Build is failing
the entire './public' folder that Hugo produces is embedded into a
variable of 'embed.FS' type and served directly using the default http
mux that Go std offers.

ci, pre-commit, Dockerfile and compose file have all been updated
accordingly.

nginx is no longer needed to front the site files, which enabled
switching to a SCRATCH image containing just a single statically linked
"homepage" app that has all files (html, css, js) embedded.
the containers are otherwise empty (as the name SCRATCH suggests), which
further decreases potential attack surface area.

Co-authored-by: surtur <a_mirre@utb.cz>
Reviewed-on: #33
2022-08-08 15:20:50 +02:00
d0c61e4847
add yamllint [skip ci] 2022-08-02 15:13:39 +02:00
20c220ffee
compose: add memory limits
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-02 15:08:18 +02:00
20665dc119
chore: fix compose's yaml [skip ci] 2022-08-02 15:07:02 +02:00
0a3136a291
bump traefik to 2.8.1
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-18 17:40:05 +02:00
ffd7a943f4
fix .pre-commit-config.yaml [skip ci] 2022-07-02 17:20:01 +02:00
a8ac5aa872
pre-commit: check compose file
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-02 17:18:27 +02:00
c99432ea52
bump traefik to 2.8.0
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-02 17:07:45 +02:00
ee7acd7c1b
bump traefik to 2.7.3
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-02 17:06:27 +02:00
2c4b9a8546
bump traefik to 2.7.2
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-02 17:05:52 +02:00
c6a7db63d7
pin traefik to 2.7.1
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-02 17:03:19 +02:00
30be2871f2
nginx: redirect 404 to /404.html
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-05 16:27:51 +02:00
1432f7e50d
use relref shortcode for site-local links
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-30 17:59:37 +02:00
bb5d6b632e
only solve for rss as alternative output format
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-30 17:45:06 +02:00
0b8d7d92ae
fix 8fe0e155d3: bump traefik to version 2.7
All checks were successful
continuous-integration/drone/push Build is passing
the :2.6.3 tag is apparently only available for arm arch, it's probably
best not to base the decision to bump versions on a new release
notification. instead, availability of the new version for our default
arch (amd64) should always be checked:
    podman run -it --rm docker.io/library/traefik:2.6.3
    Trying to pull docker.io/library/traefik:2.6.3...
    Error: choosing an image from manifest list docker://traefik:2.6.3: no image found in manifest list for architecture amd64, variant "", OS linux

    ~ took 2s
    (╯°□°)╯︵ ┻━┻ 125 🔥  podman run -it --rm docker.io/library/traefik:2.7
    Trying to pull docker.io/library/traefik:2.7...
    Getting image source signatures
    Copying blob 491249faa733 done
2022-03-30 17:26:02 +02:00
8fe0e155d3
chore: bump traefik to version 2.6.3
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-30 13:45:28 +02:00
aaccd2356b
update theme colours
All checks were successful
continuous-integration/drone/push Build is passing
commit bc6140098f698dbdf9f40b17e68a93d866eb93b5
Author: surtur <a_mirre@utb.cz>
Date:   Tue Mar 29 18:32:39 2022 +0200

    add commentary to colour codes

    since we're keeping the original names of colour variables from the
    theme, it's a good idea to at least have the usage of them (somewhat)
    documented.

commit 927909be604187b8e178ce009d88ac6b26c0b3c5
Author: surtur <a_mirre@utb.cz>
Date:   Tue Mar 29 18:24:43 2022 +0200

    increase pre border-radius to 5px

commit 62f0d1654028beb625453ad19b0138574e999861
Author: surtur <a_mirre@utb.cz>
Date:   Tue Mar 29 18:18:02 2022 +0200

    change theme colours
2022-03-29 18:37:04 +02:00
26 changed files with 1011 additions and 215 deletions

@ -11,26 +11,32 @@ trigger:
exclude: [push, pull_request]
steps:
- name: fedora-hugo
- name: alpine-hugo
pull: always
image: immawanderer/fedora-hugo:linux-amd64
image: docker.io/immawanderer/alpine-hugo:hugo-v0.115.3
commands:
- uname -r
- cat /etc/fedora-release
- hugo version
- name: alpine-rsync
pull: always
image: immawanderer/alpine-rsync:latest
image: docker.io/immawanderer/alpine-rsync:latest
commands:
- uname -r
- name: hadolint
pull: always
image: hadolint/hadolint:2.9.1-alpine
image: docker.io/hadolint/hadolint:2.10.0-alpine
commands:
- uname -r
- hadolint --version
- name: golang
pull: always
image: docker.io/library/golang:1.21.0-alpine3.18
commands:
- uname -r
- go version
---
kind: pipeline
type: docker
@ -47,16 +53,65 @@ trigger:
depends_on:
- pull
environment:
CGO_ENABLED: 0
steps:
- name: hugo-extended
pull: if-not-exists
image: immawanderer/fedora-hugo:linux-amd64
- name: submodules
image: docker.io/alpine/git:v2.36.2
depends_on: [clone]
commands:
- git submodule init
- git submodule update
- git submodule update --recursive
- name: hugo-extended
pull: always
image: docker.io/immawanderer/alpine-hugo:hugo-v0.115.3
depends_on: [submodules]
commands:
- hugo version
- hugo --gc=true --minify
- name: go fmt
image: docker.io/library/golang:1.21.0-alpine3.18
volumes:
- name: gopath
path: /go
depends_on:
- clone
commands:
- go fmt
- name: go vet
image: docker.io/library/golang:1.21.--alpine3.18
volumes:
- name: gopath
path: /go
depends_on:
- go fmt
commands:
- go vet
- name: go build
pull: if-not-exists
image: docker.io/library/golang:1.21.0-alpine3.18
volumes:
- name: gopath
path: /go
depends_on:
- go vet
# wait until the site is output into './public'.
- hugo-extended
environment:
GOFLAGS: -trimpath -mod=readonly -modcacherw
commands:
- go build -v -ldflags "-s -w -X main.Version=${DRONE_COMMIT}" .
volumes:
- name: gopath
temp: {}
---
kind: pipeline
type: docker
@ -75,14 +130,16 @@ depends_on:
steps:
- name: hadolint
image: hadolint/hadolint:v2.9.1-alpine
image: docker.io/hadolint/hadolint:v2.10.0-alpine
depends_on: [clone]
commands:
- hadolint --version
- hadolint Dockerfile
- name: build
- name: check compose
pull: always
image: tmaier/docker-compose:latest
image: docker.io/tmaier/docker-compose:latest
depends_on: [clone]
volumes:
- name: s
path: /var/run/docker.sock
@ -90,12 +147,25 @@ steps:
COMPOSE_DOCKER_CLI_BUILD: 1
DOCKER_BUILDKIT: 1
commands:
- docker-compose build --no-cache --pull
- docker compose -f docker-compose.yml config -q
- name: build
pull: always
image: docker.io/tmaier/docker-compose:latest
depends_on: [hadolint, check compose]
volumes:
- name: s
path: /var/run/docker.sock
environment:
COMPOSE_DOCKER_CLI_BUILD: 1
DOCKER_BUILDKIT: 1
commands:
- docker compose build --build-arg VCS_REF=${DRONE_COMMIT} --no-cache --pull
volumes:
- name: s
host:
path: /var/run/docker.sock
path: /run/docker.sock
---
@ -117,18 +187,24 @@ depends_on:
- build
steps:
- name: hugo-extended
pull: if-not-exists
image: immawanderer/fedora-hugo:linux-amd64
- name: submodules
image: docker.io/alpine/git:v2.36.2
depends_on: [clone]
commands:
- git submodule init
- git submodule update
- git submodule update --recursive
- name: hugo-extended
pull: always
image: docker.io/immawanderer/alpine-hugo:hugo-v0.115.3
depends_on: [submodules]
commands:
- hugo version
- hugo --gc=true --minify
- name: deploy
pull: if-not-exists
image: alpine:3.15.0
image: docker.io/library/alpine:3.15.0
when:
status:
- success
@ -178,57 +254,118 @@ node:
depends_on:
- build
environment:
CGO_ENABLED: 0
steps:
- name: hugo-extended
pull: if-not-exists
image: immawanderer/fedora-hugo:linux-amd64
- name: submodules
image: docker.io/alpine/git:v2.36.2
depends_on: [clone]
commands:
- git submodule init
- git submodule update
- git submodule update --recursive
- name: hugo-extended
pull: always
image: docker.io/immawanderer/alpine-hugo:hugo-v0.115.3
depends_on: [submodules]
commands:
- hugo version
- hugo --gc=true --minify
- name: rm-intermediate
pull: if-not-exists
image: immawanderer/fedora-hugo:linux-amd64
depends_on:
- hugo-extended
commands:
- rm -rf ./public
- name: hadolint
image: hadolint/hadolint:v2.9.1-alpine
image: docker.io/hadolint/hadolint:v2.10.0-alpine
depends_on:
- clone
commands:
- hadolint --version
- hadolint Dockerfile
- name: check compose
pull: always
image: docker.io/tmaier/docker-compose:latest
depends_on: [clone]
volumes:
- name: s
path: /var/run/docker.sock
environment:
COMPOSE_DOCKER_CLI_BUILD: 1
DOCKER_BUILDKIT: 1
commands:
- docker compose -f docker-compose.yml config -q
- name: go fmt
image: docker.io/library/golang:1.21.0-alpine3.18
volumes:
- name: gopath
path: /go
depends_on:
- clone
commands:
- go fmt
- name: go vet
image: docker.io/library/golang:1.21.0-alpine3.18
volumes:
- name: gopath
path: /go
depends_on:
- go fmt
# wait until the site is output into './public'.
- hugo-extended
commands:
- go vet
- name: go build
image: docker.io/library/golang:1.21.0-alpine3.18
volumes:
- name: gopath
path: /go
depends_on:
- go vet
commands:
- go build -v -ldflags "-s -w -X main.Version=${DRONE_COMMIT}" .
- name: rm-intermediate
pull: if-not-exists
image: docker.io/immawanderer/fedora-hugo:linux-amd64
depends_on:
- go build
commands:
- rm -rf ./public
- name: build
pull: always
image: tmaier/docker-compose:latest
image: docker.io/tmaier/docker-compose:latest
depends_on:
- rm-intermediate
- hadolint
- check compose
- go fmt
- go vet
- go build
volumes:
- name: s
path: /var/run/docker.sock
commands:
- docker-compose build --no-cache
- docker compose build --build-arg VCS_REF=${DRONE_COMMIT} --no-cache
when:
branch: master
status: success
- name: deploy
pull: always
image: tmaier/docker-compose:latest
image: docker.io/tmaier/docker-compose:latest
depends_on:
- build
volumes:
- name: s
path: /var/run/docker.sock
commands:
- docker-compose -p ${DRONE_REPO_NAME} up -d --remove-orphans --scale homepage=4
- docker compose -p ${DRONE_REPO_NAME} up
-d
--remove-orphans
--scale homepage=1
when:
branch: master
status: success
@ -236,7 +373,9 @@ steps:
volumes:
- name: s
host:
path: /var/run/docker.sock
path: /run/docker.sock
- name: gopath
temp: {}
---
@ -266,7 +405,7 @@ depends_on: [deploy, deploy-staging]
steps:
- name: discord
pull: if-not-exists
image: appleboy/drone-discord:latest
image: docker.io/appleboy/drone-discord:latest
settings:
message: >
{{#success build.status}}
@ -306,7 +445,7 @@ depends_on: [deploy]
steps:
- name: discord
pull: always
image: appleboy/drone-discord:latest
image: docker.io/appleboy/drone-discord:latest
settings:
message: >
{{#success build.status}}
@ -324,3 +463,9 @@ steps:
from_secret: discord_webhook_hourly_id
webhook_token:
from_secret: discord_webhook_hourly_token
---
kind: signature
hmac: 4e178bb873563499a7b3b00fdb372acc239dedfb8b151858598a29778349f44c
...

3
.gitignore vendored

@ -2,3 +2,6 @@
public/
resources/
*.swp
# go binary
homepage

96
.golangci.yml Normal file

@ -0,0 +1,96 @@
---
run:
go: '1.20'
tests: true
skip-dirs:
- static
- public
issues:
max-issues-per-linter: 0
max-same-issues: 0
linters:
enable:
- bidichk
- dupl
- decorder
- dogsled
- exportloopref
- forbidigo
- gas
- gocognit
- goconst
- gocritic
- godot
- govet
- gofmt
- gofumpt
- goimports
- goprintffuncname
- gosec
- ineffassign
- misspell
# - prealloc
- revive
- tparallel
- unconvert
- unparam
- unused
- wastedassign
- whitespace
- wsl
linter-settings:
dupl:
threshold: 100
gocritic:
enabled-tags:
- diagnostic
- experimental
- opinionated
- performance
- style
disabled-checks:
- dupImport # https://github.com/go-critic/go-critic/issues/845
- ifElseChain
- octalLiteral
- whyNoLint
- wrapperFunc
gocyclo:
min-complexity: 15
gofumpt:
extra-rules: true
lang-version: "1.20"
govet:
check-shadowing: true
revive:
severity: warning
confidence: 0.8
errorCode: 1
warningCode: 1
rules:
- name: blank-imports
- name: context-as-argument
- name: context-keys-type
- name: dot-imports
- name: error-return
- name: error-strings
- name: error-naming
- name: exported
- name: if-return
- name: increment-decrement
- name: var-naming
- name: var-declaration
- name: package-comments
- name: range
- name: receiver-naming
- name: time-naming
- name: unexported-return
- name: indent-error-flow
- name: errorf
- name: duplicated-imports
- name: modifies-value-receiver
wsl:
allow-cuddle-declaration: true
...

@ -1,3 +1,4 @@
---
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
@ -6,3 +7,41 @@ repos:
- id: check-toml
- id: check-yaml
exclude: .drone.yml # drone's yaml is somewhat strange sometimes
- repo: local
hooks:
- id: hugo-version-check
name: hugo version check
entry: |
bash -c "
files='.drone.yml Dockerfile'
count=$(grep -oE '(hugo-v)[0-9].[0-9].[0-9].[0-9]' $files | cut -d':' -f2 | sed -e 's/^ *//g' -e 's/hugo-v//g' | uniq | wc -l)
if [ $count -gt 1 ]; then
echo hugo versions inconsistent:
grep -noE --color=always '(hugo-v)[0-9].[0-9].[0-9].[0-9]' $files
exit 1
fi
"
language: system
pass_filenames: false
- id: check-compose-file
name: check compose file
language: system
entry: docker-compose -f docker-compose.yml config
pass_filenames: false
- id: yamllint
name: yamllint
language: system
entry: yamllint .
pass_filenames: false
- repo: https://git.dotya.ml/wanderer/hadolint-pre-commit
rev: v0.0.1
hooks:
- id: hadolint-container
- repo: https://github.com/dnephin/pre-commit-golang
rev: v0.5.0
hooks:
- id: go-mod-tidy
- id: go-unit-tests
- id: golangci-lint
- id: go-build
...

13
.yamllint Normal file

@ -0,0 +1,13 @@
---
yaml-files:
- '*.yaml'
- '*.yml'
- '.yamllint'
rules:
line-length:
level: warning
# vim: ft=yaml bs=2 ts=2
...

@ -1,28 +1,36 @@
FROM immawanderer/fedora-hugo:linux-amd64 AS hugobuild
RUN mkdir -pv /homepage
COPY . /homepage
# syntax=docker/dockerfile-upstream:master-labs
# refs:
# https://docs.docker.com/develop/develop-images/build_enhancements/#overriding-default-frontends
# https://pythonspeed.com/articles/docker-buildkit/
FROM docker.io/alpine/git:v2.36.2 AS submodules
WORKDIR /homepage
RUN git submodule init \
&& git submodule update --recursive \
&& hugo version
# "DL3059 info: Multiple consecutive `RUN` instructions.
# Consider consolidation."
# hadolint ignore=DL3059
RUN hugo --minify --gc=true
COPY . .
WORKDIR /
RUN git submodule init && \
git submodule update --recursive
FROM nginx:mainline-alpine
COPY --from=hugobuild /homepage/public/ /usr/share/nginx/html
FROM docker.io/immawanderer/alpine-hugo:hugo-v0.115.3 AS hugobuild
# tripple slash reference
# https://stackoverflow.com/questions/5190966/using-sed-to-insert-tabs/5191165#5191165
RUN sed -i -e 's/^worker_processes auto;/worker_processes auto;/'\
-e "/^events {$/ a \\\tmulti_accept on;\n\tuse epoll;"\
-e "/^http {$/ a \\\tserver_tokens off;\n\tetag off;\n"\
-e 's/#tcp_nopush/tcp_nopush/'\
-e "/tcp_nopush/ a \\\ttcp_nodelay on;"\
-e "s/^ */$(printf '\t')/"\
/etc/nginx/nginx.conf
COPY --from=submodules /homepage/ /homepage/
WORKDIR /homepage
RUN hugo version && \
hugo --minify --gc=true --cleanDestinationDir
FROM docker.io/library/golang:1.21.0-alpine3.18 AS gobuild
COPY --from=hugobuild /homepage/ /homepage/
WORKDIR /homepage
ARG VCS_REF=development
RUN CGO_ENABLED=0 GOFLAGS='-trimpath -mod=readonly -modcacherw' \
go build -o homepage-app -v -ldflags "-s -w -X main.version=$VCS_REF" .
FROM scratch
COPY --from=gobuild /homepage/homepage-app /homepage
ENTRYPOINT ["/homepage"]

@ -1,5 +1,6 @@
# dotya.ml
# [dotya.ml](https://git.dotya.ml/dotya.ml/homepage/)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
[![Build Status](https://drone.dotya.ml/api/badges/dotya.ml/homepage/status.svg?ref=refs/heads/master)](https://drone.dotya.ml/dotya.ml/homepage)
[![Mozilla HTTP Observatory Grade](https://img.shields.io/mozilla-observatory/grade-score/dotya.ml)](https://observatory.mozilla.org/analyze/dotya.ml)
[![Security Headers](https://img.shields.io/security-headers?url=https%3A%2F%2Fdotya.ml)](https://securityheaders.com/?q=https%3A%2F%2Fdotya.ml)

@ -1,6 +1,8 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
lastmod: {{ .Date }}
enableGitInfo: true
draft: true
---

@ -1,11 +1,12 @@
// Colors
//
$theme: #D8D8D8;
$text: #D8D8D8;
$light-grey: #282a2b; // Background
$dark-grey: #282a2b; // Hover Bar
$highlight-grey: #151718; // Highlight background of `keyword`
$midnightblue: #151718; // Code Background
$theme: #613583; // hyperlink highlight background colour, .post-info
// site-local link :hover highlight colour
$text: #21fa45; // colour of normal text
$light-grey: #010000; // background
$dark-grey: #111115; // hover bar
$highlight-grey: #9141ac; // code (not in pre) background
$midnightblue: #151718; // code text (not in pre) colour
// Fonts
//

@ -48,19 +48,20 @@ pre {
letter-spacing: normal;
white-space: pre;
color: #eee;
background: $midnightblue;
border-radius: 4px;
background: transparent;
border-radius: 5px;
// -webkit-overflow-scrolling: touch;
code {
padding: 0;
margin: 0;
background: $midnightblue;
color: #eee;
background: transparent;
}
}
code {
color: #eee;
color: $midnightblue;
background: $highlight-grey;
border-radius: 3px;
padding: 0 3px;
@ -94,8 +95,7 @@ a {
transition-timing-function: ease-out;
&:hover {
color: #fff;
text-shadow: 0 0 1px #fff;
color: $highlight-grey;
}
}
@ -380,6 +380,7 @@ p.img-404 {
&:hover {
border-color: #fff;
color: $highlight-grey;
}
svg {

@ -6,6 +6,7 @@ enableGitInfo = true
pygmentsCodefences = true
pygmentsUseClasses = true
pygmentsStyle = "fruity"
enableEmoji = true
[author]
@ -14,11 +15,14 @@ enableEmoji = true
[taxonomies]
tag = 'tags'
[permalinks]
posts = '/:year/:month/:title/'
[params]
dateform = "Jan 2, 2006"
dateformShort = "Jan 2"
dateformNum = "2006-02-01"
dateformNumTime = "2006-02-01T15:04+00:00"
dateform = "02 Jan 2006"
dateformShort = "02 Jan"
dateformNum = "02 Jan 2006"
dateformNumTime = "Mon, 02 Jan 2006 15:04:05 -0700"
# Metadata mostly used in document's head
description = "dotya.ml homepage"
keywords = "homepage, development, git, programming"
@ -56,36 +60,38 @@ enableEmoji = true
alt = "dockerhub profile page"
[languages]
[languages.logo.params.en]
logoText = "dotya.ml"
logoHomeLink = "/"
[languages.en]
title = "dotya.ml"
subtitle = ""
[languages.en.params]
keywords = "homepage, development, git, programming"
subtitle = "hello friend. hello friend? that's lame. maybe I should give you a name."
readOtherPosts = ""
[languages.en.params.logo]
logoText = "dotya.ml"
logoHomeLink = "/"
# You can create a language based menu
[languages.en.menu]
[[languages.en.menu.main]]
identifier = "about"
name = "about"
url = "/about/"
alt = "dotya.ml status"
weight = 1
[[languages.en.menu.main]]
identifier = "posts"
name = "posts"
url = "/posts/"
alt = "dotya.ml posts"
weight = 2
[[languages.en.menu.main]]
identifier = "contact"
name = "contact"
url = "/contact/"
alt = "dotya.ml contact"
weight = 3
# You can create a language based menu
[languages.en.menu]
[[languages.en.menu.main]]
identifier = "about"
name = "about"
url = "/about/"
alt = "about dotya.ml"
weight = 1
[[languages.en.menu.main]]
identifier = "posts"
name = "posts"
url = "/posts/"
alt = "dotya.ml posts"
weight = 2
[[languages.en.menu.main]]
identifier = "contact"
name = "contact"
url = "/contact/"
alt = "dotya.ml contact"
weight = 3
[privacy]
[privacy.disqus]

@ -1,5 +1,6 @@
---
title: "0x28bd2388"
description: "instructions on how to verify 0x28bd2388 gpg key"
date: 2020-03-07T16:22:03+01:00
draft: false
---

@ -1,49 +1,29 @@
---
title: "about dotya.ml"
description: "an overview of dotya.ml's activities and mission"
date: 2020-08-06T17:15:03+01:00
lastmod: 2022-09-06T16:11:32+02:00
draft: false
---
Free services provided for fun as a hobby with passion and :white_heart:\
So far we have:
* [Gitea](https://gitea.io) SCM instance at https://git.dotya.ml
* [DroneCI](https://drone.io) instance (login with a Gitea account) at https://drone.dotya.ml
* [DNSCrypt](https://dnscrypt.info/) server
Free services provided for fun as a hobby with passion and :white_heart:
### Clearnet services
see what we have so far: [list of services]({{< relref "services.md" >}}).
### Onion services
> Note: This is a work in progress - more services are to come
Gitea: http://2crftbzxbcoqolvzreaaeyrod5qwycayef55gxgzgfcpqlaxrnh3kkqd.onion\
this site: http://6426tqrh4y5uobmo5y2csaip3m3avmjegd2kpa24sadekpxglbm34aqd.onion\
prometheus: http://vognfwm7c6wq2gxqcmswi2flwckuxryefd7n3axxkvlpasdjhns5buqd.onion\
grafana: http://6t3ydf7sl7iso2wbymbfjtaq6qqlrms37ffik2siulsljc3ubobklnid.onion\
statuspage: http://o4irro4dspyuytbw2b2g2ac4ukkh2ex53oolhzw7hrfjmq6tiklrtwqd.onion
#### current progress on onion drone
https://git.dotya.ml/dotya.ml/community/issues/5
Making `DroneCI` available as a hidden service would require either
a) spinning up another instance, for which we currently don't have capacities, or
b) some kind of an evil hack that we've not yet discovered.\
We're open to ideas - if you know how to make this work, please, send us a patch,
PR or an email with anything interesting and worthwile.
set-up-but-not-properly-working drone: http://c3vqfx2dqltvdbsqu3ndqwcxsp3uk3vcxo2jsigie5zfajub3j3y35id.onion
### DNS(Crypt)
a non-logging name server, securing connections using DNSCrypt for increased
privacy, that is - as long as we trust our own server.
see [DNSCrypt](/posts/dnscrypt/) for more.
for increased privacy of our users, *some* services are also available
natively via [TOR](https://www.torproject.org/), have a look at
[onions 🧅]({{< relref "onions.md" >}}) for details.
### Observability
long-term monitoring of trends for services we're running
to enable long-term monitoring of trends for services we're running:
* [prometheus](https://prometheus.io) at https://metrics.dotya.ml
* [grafana](https://grafana.com) at https://grafana.dotya.ml
### Status
* in-house status monitor at https://status.dotya.ml
* UptimeRobot hosted dashboard at https://stats.uptimerobot.com/93yPqFmmx8
* in-house status monitor at https://status.dotya.ml (courtesy of [statping-ng](https://statping-ng.github.io))
* UptimeRobot ([affiliate link](https://uptimerobot.com/?rid=a60f8392870bc9)) hosted dashboard at https://stats.uptimerobot.com/93yPqFmmx8
### Security
[HSTS](https://tools.ietf.org/rfc/rfc6797.txt) has been enabled early on for `dotya.ml`,
@ -59,3 +39,9 @@ Scoring 130 out of 100 points
* [SecurityHeaders](https://securityheaders.com/) report at https://securityheaders.com/?q=https%3A%2F%2Fdotya.ml
* SSL Labs [TLS rating](https://www.ssllabs.com/ssltest/analyze.html?d=dotya.ml): *A+*
* [cryptcheck.fr](https://cryptcheck.fr/https/dotya.ml): *A+*
### Privacy
see [privacy]({{< relref "privacy" >}}), the short version being *we are not
selling you out* 🎉.

@ -1,27 +1,31 @@
---
title: "contact"
description: "ways to get in contact with dotya.ml maintainers"
date: 2020-03-07T01:53:03+01:00
draft: false
---
\-- wanderer
## \-- wanderer
```bash
echo a_mirre.utb.cz | sed 's/\./@/'
echo wanderer+hello.dotya.ml | sed 's/\./@/'
```
fingerprint:
use [age](https://github.com/FiloSottile/age) if possible.\
pubkey:
```sh
age16xdcxvnnhcekv59ncj5fmdarhm8csdgd9nk7nzxpywg5xtehq4kq49880e
```
gpg fingerprint:
```bash
E860 AB3C D007 8D30 E86C DA74 7B28 D8DC 28BD 2388
```
the corresponding pubkey: [0x28bd2388](/28bd2388/)
the corresponding pubkey: [0x28bd2388]({{< relref "28bd2388.md" >}})
plain key file: [0x28bd2388.asc](/store/0x28bd2388.asc)
openpgp key server link: [0x28bd2388](https://keys.openpgp.org/vks/v1/by-fingerprint/E860AB3CD0078D30E86CDA747B28D8DC28BD2388)
\
\-- 2EEEB
## \-- 2EEEB
```bash
echo andrej.pillar,vutbr.cz | sed 's/\,/@/'
```
@ -35,21 +39,12 @@ the pubkey can be found in a [key repo](https://keyserver.ubuntu.com/pks/lookup?
communication using gpg is *preferable*
## privacy
### tl;dr
[Access logs](https://en.wikipedia.org/wiki/Server_log) are stored for up to 30 days for the purpose of defending against abuse.
### the long version
Since I don't like such practices myself, this site *does not* collect
*any* kind of user/browser/device/user agent/network identifier,
which - for simplicity's sake is - no data at all - **FOR PROFIT**.\
Period.
No personally identifiable data is collected - actively or passively - and therefore can't be passed on to third parties (such as advertisement companies), nor is there any intention of *ever* doing so.
Visitor device's apparent IP address *is stored* in access log, along with a [user agent](https://duckduckgo.com/?t=ffab&q=user+agent) string, which allows us to defend against abuse.
These logs are automatically overwriten approximately every 30 days.
## Privacy
see [privacy]({{< relref "about#privacy" >}}), or in case of questions, say
hi and ask away at:
```sh
hello at dotya dot ml
```
## Long live the libre world!

42
content/onions.md Normal file

@ -0,0 +1,42 @@
---
title: "onions 🧅"
description: "summary of onion services dotya.ml provides - a more anonymous way to access your stuff"
date: 2022-08-30T12:00:42+02:00
lastmod: 2022-08-30T12:00:42+02:00
enableGitInfo: true
draft: false
---
> Note: This is a work in progress - more services are to come
> Note 2: the `http` part of the links below is misleading, as (our) [onion
> services](https://community.torproject.org/onion-services/) are in fact
> fully encrypted every step of the way using `https`, only the certs are not
> signed by a conventional CA (certificate authority), which means
> conventional browsers (including Firefox-based TorBrowser) would cry if the
> sites were served with explicit `https` prefix.
> this decreases the security by exactly zero and unless LetsEncrypt starts
> issuing certs for `.onion` domains, we're not going to see broad usage of
> *explicit* `https` prefix on onion services, since only the likes of NY
> Times, BBC, Twitter or Facebook are going to make their CAs to sign them a
> neat little `.onion` cert.
Gitea: http://2crftbzxbcoqolvzreaaeyrod5qwycayef55gxgzgfcpqlaxrnh3kkqd.onion\
this site: http://6426tqrh4y5uobmo5y2csaip3m3avmjegd2kpa24sadekpxglbm34aqd.onion\
prometheus: http://vognfwm7c6wq2gxqcmswi2flwckuxryefd7n3axxkvlpasdjhns5buqd.onion\
grafana: http://6t3ydf7sl7iso2wbymbfjtaq6qqlrms37ffik2siulsljc3ubobklnid.onion\
statuspage: http://o4irro4dspyuytbw2b2g2ac4ukkh2ex53oolhzw7hrfjmq6tiklrtwqd.onion
#### current progress on onion drone
https://git.dotya.ml/dotya.ml/community/issues/5
Making `DroneCI` available as a hidden service would require either
a) spinning up another instance, for which we currently don't have capacities, or
b) some kind of an evil hack that we've not yet discovered.\
We're open to ideas - if you know how to make this work, please, send us a patch,
PR or an email with anything interesting and worthwile.
set-up-but-not-properly-working drone: http://c3vqfx2dqltvdbsqu3ndqwcxsp3uk3vcxo2jsigie5zfajub3j3y35id.onion
### clearnet
also check out [services]({{< relref "services" >}})...

@ -1,45 +1,118 @@
---
title: "DNSCrypt"
title: "DNSCrypt - running the server"
description: "How we run a DNSCrypt server using docker-compose"
date: 2021-08-06T23:38:45+02:00
author: wanderer - https://git.dotya.ml/wanderer
draft: false
toc: true
enableGitInfo: true
tags: [dnscrypt, dns, privacy, security, censorship]
---
### why are you doing this?
## why are you doing this?
There are many publicly available [open resolvers using DoT, DoH or
DNSCrypt](https://dnscrypt.info/public-servers) to secure the traffic. However,
we have still felt the need to run our own, especially since it's such a
critical part of the infrastructure. Since now it's a reality, we're offering
it for public use.
DNSCrypt](https://dnscrypt.info/public-servers) just sitting around the
interwebs, waiting to secure the DNS traffic and protect it from whoever is
looking.
### so what is it?
However, we have still felt the need to run our own, especially since
DNS is such a critical piece of infrastructure.
And now we're offering it for public use.
## so what is it?
What we're running is a non-censoring, non-logging, DNSSEC-capable, DNSCrypt-enabled DNS
resolver using
[dnscrypt-server-docker](https://github.com/dnscrypt/dnscrypt-server-docker) project.
Our resolver is available over both IPv4 and IPv6.
Of course, our resolver is available over both IPv4 and IPv6.
### can I haz some plz
> Since the name servers are not (yet) a part of any listing of public
> resolvers, entries have to be added manually.
## can I haz some plz
Yes! As a matter of fact, you should even be able to get records on
[OpenNIC](https://www.opennic.org/) domains.
You can try some using the awesome tool [`doggo`](https://github.com/mr-karan/doggo), like so:
```shell
doggo --debug --json NS epic. @sdns://AQcAAAAAAAAAETE0NC45MS43MC42Mjo1NDQzIHF-JiN46cNwFXJleEVWGWgrhe2QeysUtZoo9HwzYCMzITIuZG5zY3J5cHQtY2VydC5kbnNjcnlwdC5kb3R5YS5tbA
```
example response:
```shell
DEBUG[2022-09-01T00:22:23+02:00] initiating DNSCrypt resolver
DEBUG[2022-09-01T00:22:23+02:00] Starting doggo 🐶
DEBUG[2022-09-01T00:22:23+02:00] Attempting to resolve domain=epic. nameserver="144.91.70.62:5443" ndots=0
[
{
"answers": [
{
"name": "epic.",
"type": "NS",
"class": "IN",
"ttl": "86400s",
"address": "ns13.opennic.glue.",
"status": "",
"rtt": "45ms",
"nameserver": "144.91.70.62:5443"
}
],
"authorities": null,
"questions": [
{
"name": "epic.",
"type": "NS",
"class": "IN"
}
]
}
]
```
### `dnscrypt-proxy` configuration tips
If you'd, for some reason, like to use exclusively our name servers, simply set
the `server_names` in the root section of your `dnscrypt-proxy.toml` config
file:
```toml
server_names = ['dotya.ml', 'dotya.ml-ipv6']
```
By default servers are picked based on latency, which is a sane default and it
is in fact what we use.
If in need of more granular nameserver selection based on anything other than
latency they can additionally easily be filtered (without being explicitly
listed) based on:
* logging
* filtering
* DNSSEC capabilities
* DoH, ODoH or DNSCrypt capabilities
* IPv4 or IPv6 availability
Further, we also remove certain players from the equation by simply listing
them in `disabled_server_names`, like so:
```toml
disabled_server_names = ['google-ipv6', 'cloudflare', 'cloudflare-ipv6', 'cisco', 'cisco-ipv6', 'cisco-familyshield', 'cisco-familyshield-ipv6', 'yandex', 'apple', 'doh.dns.apple.com']
```
### old news
> Update 2022-09-01: the servers are now a part of the official listing at
> https://dnscrypt.info/public-servers/, so there is no point in adding them
> manually anymore. Keeping this for posterity.
Paste one or both of the following entries in the `[static]` section of your
`dnscrypt-proxy.toml` configuration file.
IPv4 (`144.91.70.62`)
```toml
[static. 'dnscrypt.dotya.ml-ipv4']
stamp = 'sdns://AQcAAAAAAAAAETE0NC45MS43MC42Mjo1NDQzIHF-JiN46cNwFXJleEVWGWgrhe2QeysUtZoo9HwzYCMzITIuZG5zY3J5cHQtY2VydC5kbnNjcnlwdC5kb3R5YS5tbA'
[static]
# IPv4 (144.91.70.62, port 5443)
[static. 'dnscrypt.dotya.ml-ipv4']
stamp = 'sdns://AQcAAAAAAAAAETE0NC45MS43MC42Mjo1NDQzIHF-JiN46cNwFXJleEVWGWgrhe2QeysUtZoo9HwzYCMzITIuZG5zY3J5cHQtY2VydC5kbnNjcnlwdC5kb3R5YS5tbA'
# IPv6 (2a02:c207:2030:396::1, port 5443)
[static. 'dnscrypt.dotya.ml-ipv6']
stamp = 'sdns://AQcAAAAAAAAAHFsyYTAyOmMyMDc6MjAzMDozOTY6OjFdOjU0NDMgcX4mI3jpw3AVcmV4RVYZaCuF7ZB7KxS1mij0fDNgIzMhMi5kbnNjcnlwdC1jZXJ0LmRuc2NyeXB0LmRvdHlhLm1s'
```
IPv6 (`2a02:c207:2030:396::1`)
```toml
[static. 'dnscrypt.dotya.ml-ipv6']
stamp = 'sdns://AQcAAAAAAAAAHFsyYTAyOmMyMDc6MjAzMDozOTY6OjFdOjU0NDMgcX4mI3jpw3AVcmV4RVYZaCuF7ZB7KxS1mij0fDNgIzMhMi5kbnNjcnlwdC1jZXJ0LmRuc2NyeXB0LmRvdHlhLm1s'
```
### Configuration
## server configuration
Files used to set up and run this service can be found here:\
https://git.dotya.ml/dotya.ml/dnscrypt-server.
It's a `docker-compose` setup managed with `systemd`, similar to how Drone CI

157
content/posts/m32.md Normal file

@ -0,0 +1,157 @@
---
title: "Compiling C programs using -m32 on Arch in 2023"
description: "Compiling C programs for 32bit on Arch in 2023"
date: 2023-06-14T12:32:52+02:00
author: wanderer - https://git.dotya.ml/wanderer
draft: false
toc: true
enableGitInfo: true
images:
tags:
- archlinux
- compilation
- 32bit
---
## Intro
> **Preliminary:** To be clear, this short post is not primarily concerned with
> *running* the 32bit programs, instead specifically *compiling C programs for
> 32bit (x86)*.
Compiling a `C` program for a 32bit architecture in 2023?
Well, one might still want to poke at reversing smaller address-space programs,
*even in 2023*, and contrary to the popular belief, there still exist pieces of
software not ported to 64bit and architectures in use that are 32bit. Whatever
the motivation, the *compilation* process might not be as straight-forward on
Arch as one would maybe expect, so this post shows how it can be done. Unless
specified otherwise, the `x86` architecture is assumed.
### Example program
> Just show the example program already!
Nothing fancy, just saying hi and printing the value of `esp`. All that is
needed is to compile this into a 32bit binary.
```c
/* 32ftw.c */
#include <stdio.h>
int main() {
printf("hey 32!\n");
register int e asm("esp");
printf("esp: 0x%08x\n", e);
return 0;
}
```
For reference, the`GCC` version used was `gcc (GCC) 13.1.1 20230429`.
## TL;DR
To compile a 32bit `C` program on
[64bit-only](https://wiki.archlinux.org/title/Frequently_asked_questions#What_architectures_does_Arch_support?)
Arch, additional packages (on top of compilers/linkers) are required. As of
2023-06-14 these are:
* `core/lib32-glibc`
* `core/libr32-gcc-libs`,
which are the GNU C library (could also use [musl libc](https://musl.libc.org/)
but that would probably necessitate compiler wrapping as GCC seems to prefer
the GNU versions), and the 32bit version of the GCC libraries, respectively.
### Installing deps and calling it a day
```sh
~ % sudo pacman -S lib32-glibc lib32-gcc-libs
resolving dependencies...
looking for conflicting packages...
Package (2) New Version Net Change
core/lib32-gcc-libs 13.1.1-1 113.12 MiB
core/lib32-glibc 2.37-3 18.06 MiB
Total Installed Size: 131.18 MiB
:: Proceed with installation? [Y/n]
```
## The longer version
If you ever needed to compile some `C` sources (such as the example listed
[here](#example-program)) on Arch into a 32 bit binary? You might have
encountered the following:
```sh
~ % gcc -o 32ftw -m32 32ftw.c && ./32ftw
In file included from /usr/include/features.h:515,
from /usr/include/bits/libc-header-start.h:33,
from /usr/include/stdio.h:27,
from 32ftw.c:2:
/usr/include/gnu/stubs.h:7:11: fatal error: gnu/stubs-32.h: No such file or directory
7 | # include <gnu/stubs-32.h>
| ^~~~~~~~~~~~~~~~
compilation terminated.
```
Alright, a quick search and [an answer on Arch
forums](https://bbs.archlinux.org/viewtopic.php?pid=1136063#p1136063) points to
a (spoiler: *partial*) solution: `lib32-glibc` is needed, so let's install it
```sh
~ % sudo pacman -S lib32-glibc
```
and try again:
```sh
~ % gcc -o 32ftw -m32 32ftw.c && ./32ftw
/usr/sbin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../libgcc_s.so.1 when searching for libgcc_s.so.1
/usr/sbin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../libgcc_s.so.1 when searching for libgcc_s.so.1
/usr/sbin/ld: skipping incompatible /usr/lib/libgcc_s.so.1 when searching for libgcc_s.so.1
/usr/sbin/ld: cannot find libgcc_s.so.1: No such file or directory
/usr/sbin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../libgcc_s.so.1 when searching for libgcc_s.so.1
/usr/sbin/ld: skipping incompatible /usr/lib/libgcc_s.so.1 when searching for libgcc_s.so.1
collect2: error: ld returned 1 exit status
```
> Oh no, it still refuses to work.
As is *somewhat* hinted in the linker's error message depicted above, the
problem can be rectified by installing the GCC libraries (the 32bit version, of
course), which in Arch's `core` repository lives under the name
`lib32-gcc-libs`:
```sh
~ % sudo pacman -S lib32-gcc-libs
```
Now the program can finally be compiled and run and we can see it's a 32bit
binary.
```sh
~ % gcc -o 32ftw -m32 32ftw.c && ./32ftw
hey 32!
esp: 0xff8d27f0
~ % file ./32ftw
32ftw: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=2ff0c8dce8f64db4960aa6aef6cd9936326e990d, for GNU/Linux 4.4.0, not stripped
~ % ldd ./32ftw
linux-gate.so.1 (0xf7f50000)
libc.so.6 => /usr/lib32/libc.so.6 (0xf7ce5000)
/lib/ld-linux.so.2 => /usr/lib/ld-linux.so.2 (0xf7f52000)
```
## Closing words
To sum up, compiling a `C` program for 32bit on contemporary Arch works fine
with just a handful of dependencies. In author's opinion, this could be
highlighted better in the Archwiki, but perhaps the target audience is so small
that it hasn't even been considered.
For a not-much-talking summary, check out [TL;DR's calling it a
day](#installing-deps-and-calling-it-a-day).

22
content/privacy.md Normal file

@ -0,0 +1,22 @@
---
title: "privacy"
description: "an overview of dotya.ml's information collection/use practices (spoiler - we don't sell your data)"
date: 2022-08-30T12:47:37+02:00
lastmod: 2022-08-30T12:47:37+02:00
enableGitInfo: true
draft: false
---
### tl;dr
[Access logs](https://en.wikipedia.org/wiki/Server_log) are stored for up to 30 days for the purpose of defending against abuse.
### the long version
Since I don't like such practices myself, this site *does not* collect
*any* kind of user/browser/device/user agent/network identifier,
which - for simplicity's sake is - no data at all - **FOR PROFIT**.\
Period.
No personally identifiable data is collected - actively or passively - and therefore can't be passed on to third parties (such as advertisement companies), nor is there any intention of *ever* doing so.
Visitor device's apparent IP address *is stored* in access log, along with a [user agent](https://duckduckgo.com/?t=ffab&q=user+agent) string, which allows us to defend against abuse.
These logs are automatically overwriten approximately every 30 days.

25
content/services.md Normal file

@ -0,0 +1,25 @@
---
title: "services"
description: "a non-exhaustive list of services hosted by dotya.ml available to the community"
date: 2022-08-30T11:50:50+02:00
lastmod: 2022-08-30T11:50:50+02:00
enableGitInfo: true
toc: true
draft: false
---
a non-exhaustive list of services available to the community:
* [Gitea](https://gitea.io) SCM instance at https://git.dotya.ml
* [DroneCI](https://drone.io) instance (login with a Gitea account) at https://drone.dotya.ml
* DNS resolvers:
* [DNSCrypt](https://dnscrypt.info/) resolver (see [DNSCrypt]({{< relref "posts/dnscrypt" >}}))
* [CoreDNS](https://coredns.io/) serving
[DNS-over-TLS](https://www.rfc-editor.org/rfc/rfc7858) at
`dns.dotya.ml:853`, and
[DNS-over-HTTPS](https://en.wikipedia.org/wiki/DNS_over_HTTPS) at
`https://dns.dotya.ml/dns-query`|`https://dns.dotya.ml:4053/dns-query`
([config](https://git.dotya.ml/dotya.ml/coredns)).
* [SearXNG](https://github.com/searxng/searxng) *metasearch* engine instance at https://searxng.dotya.ml/
* [tmate](https://tmate.io/) server (see https://git.dotya.ml/dotya.ml/tmate)
also check out [onions 🧅]({{< relref "onions" >}}) to learn about services accessible via TOR.

@ -1,40 +1,43 @@
---
version: '3'
services:
reverse-proxy:
image: traefik:2.6.2
command: --api=false --api.dashboard=false --providers.docker
networks:
- internal-nw
- default
ports:
- 127.0.0.1:1314:80
restart: always
volumes:
# So that traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock:ro
#reverse-proxy:
# image: docker.io/library/traefik:2.9.6
# command: --api=false --api.dashboard=false --providers.docker
# mem_limit: 64m
# networks:
# - internal-nw
# - default
# ports:
# - 127.0.0.1:1314:80
# restart: always
# volumes:
# # So that traefik can listen to the Docker events
# - /run/docker.sock:/var/run/docker.sock:ro
# healthcheck:
# # DON'T
# # test: "/usr/bin/wget -q -Y off http://localhost:80/about -O /dev/null > /dev/null 2>&1"
# # DO:
# test: "/usr/bin/wget -q -Y off http://localhost:80/about -O /dev/null 2>&-"
# interval: 10s
# retries: 20
homepage:
build:
context: .
image: homepage
mem_limit: 8m
networks:
- internal-nw
# - internal-nw
- default
ports:
- 127.0.0.1:1314:1314
restart: always
labels:
- traefik.enable=true
- traefik.http.services.homepage.loadbalancer.server.port=80
- traefik.http.routers.homepage.rule=Host(`localhost`) || Host(`127.0.0.1`) || Host(`homepage`) || Host(`6426tqrh4y5uobmo5y2csaip3m3avmjegd2kpa24sadekpxglbm34aqd.onion`)
# ref: https://stackoverflow.com/a/61976953
# ref: https://github.com/traefik/traefik/issues/563
- "traefik.http.routers.homepage.middlewares=homepage-redirectregex, homepage-replacepathregex"
- "traefik.http.middlewares.homepage-replacepathregex.replacepathregex.regex=^/tags/(.*)$$"
- "traefik.http.middlewares.homepage-replacepathregex.replacepathregex.replacement=https://dotya.ml/tags/$$1/"
- "traefik.http.middlewares.homepage-redirectregex.redirectregex.regex=^/tags$$"
- "traefik.http.middlewares.homepage-redirectregex.redirectregex.replacement=https://dotya.ml/tags/"
- "traefik.frontend.redirect.regex=^https://dotya.ml/tags/(.*)$$"
- "traefik.frontend.redirect.replacement=https://dotya.ml/tags/$$1/"
- "traefik.frontend.rule=PathPrefix:/tags;ReplacePathRegex: ^/tags/(.*) /tags/$$1/"
#labels:
# - traefik.enable=true
# - traefik.http.services.homepage.loadbalancer.server.port=1314
# - traefik.http.routers.homepage.rule=Host(`localhost`) || Host(`127.0.0.1`) || Host(`homepage`) || Host(`6426tqrh4y5uobmo5y2csaip3m3avmjegd2kpa24sadekpxglbm34aqd.onion`)
logging:
driver: json-file
@ -43,6 +46,11 @@ services:
max-file: "5"
networks:
internal-nw:
internal: true
# internal-nw:
# internal: true
default:
volumes:
none:
...

3
go.mod Normal file

@ -0,0 +1,3 @@
module git.dotya.ml/dotya.ml/homepage
go 1.20

@ -1,5 +1,5 @@
{{ define "head" }}
{{ range .AlternativeOutputFormats -}}
{{ with .OutputFormats.Get "rss" -}}
{{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
{{ end -}}
{{ if .Site.Params.bgImg -}}
@ -30,10 +30,10 @@
{{ partialCached "menu.html" . }}
</nav>
</div>
<div id="home-footer">
<div id="home-footer" role="contentinfo">
<p>
&copy; {{ now.Format "2006" }} <a href="{{ .Site.BaseURL }}">{{ .Site.Author.name }}</a>{{ .Site.Params.footerCopyright | safeHTML }} &#183; <a href="https://git.dotya.ml/dotya.ml/homepage" title="source code" target="_blank" rel="noopener">source</a> &#183; <a href="https://status.dotya.ml" title="service status" target="_blank" rel="noopener">status</a>
{{- with (not (in (.Site.Language.Get "disableKinds") "RSS")) }} &#183; <a href="{{ "index.xml" | absLangURL }}" target="_blank" title="rss"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-rss"><path d="M4 11a9 9 0 0 1 9 9"></path><path d="M4 4a16 16 0 0 1 16 16"></path><circle cx="5" cy="19" r="1"></circle></svg></a>{{ end }}
{{- with (not (in (.Site.Params.Language.Get "disabledKinds") "RSS")) }} &#183; <a href="{{ "index.xml" | absLangURL }}" target="_blank" title="rss"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-rss"><path d="M4 11a9 9 0 0 1 9 9"></path><path d="M4 4a16 16 0 0 1 16 16"></path><circle cx="5" cy="19" r="1"></circle></svg></a>{{ end }}
</p>
</div>
</div>

@ -1,3 +1,3 @@
<footer id="site-footer" class="section-inner thin animated fadeIn faster">
<footer id="site-footer" class="section-inner thin animated fadeIn faster" role="contentinfo">
<p>&copy; {{ now.Format "2006" }} <a href="{{ .Site.BaseURL }}">{{ .Site.Author.name }}</a>{{ .Site.Params.footerCopyright | safeHTML }} &#183 <a href="https://git.dotya.ml/dotya.ml/homepage" title="source code" target="_blank" rel="noopener">source</a> &#183 <a href="https://status.dotya.ml" title="service status" target="_blank" rel="noopener">status</a>{{if .Site.Params.enableGitInfo}}<br/><a href="https://git.dotya.ml/dotya.ml/homepage/commit/{{ .GitInfo.Hash }}" target="_blank" rel="noopener">commit {{ .GitInfo.AbbreviatedHash }}</a>{{end}}</p>
</footer>

File diff suppressed because one or more lines are too long

77
layouts/posts/single.html Normal file

@ -0,0 +1,77 @@
{{ define "head" }}
{{ if .Params.featuredImg -}}
<style>.bg-img {background-image: url('{{.Params.featuredImg}}');}</style>
{{- else if .Params.images -}}
{{- range first 1 .Params.images -}}
<style>.bg-img {background-image: url('{{. | absURL}}');}</style>
{{- end -}}
{{- end -}}
{{ end }}
{{ define "header" }}
{{ partial "header.html" . }}
{{ end }}
{{ define "main" }}
{{- if (or .Params.images .Params.featuredImg) }}
<div class="bg-img"></div>
{{- end }}
<main class="site-main section-inner animated fadeIn faster">
<article class="thin">
<header class="post-header">
<div class="post-meta"><span>{{ .Date.Format .Site.Params.dateform }}</span></div>
<h1>{{ .Title }}</h1>
</header>
<div class="content">
{{ .Content | replaceRE "(<h[1-6] id=\"([^\"]+)\".+)(</h[1-6]+>)" `${1}<a href="#${2}" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path><line x1="8" y1="12" x2="16" y2="12"></line></svg></a>${3}` | safeHTML }}
</div>
{{- if .Site.Params.relatedPosts }}
{{- partial "related-posts.html" . -}}
{{- end }}
<hr class="post-end">
<footer class="post-info">
{{- with $.Param "author" }}
<p><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-feather"><path d="M20.24 12.24a6 6 0 0 0-8.49-8.49L5 10.5V19h8.5z"></path><line x1="16" y1="8" x2="2" y2="22"></line><line x1="17.5" y1="15" x2="9" y2="15"></line></svg>{{ . }}</p>
{{- end }}
{{- with .Params.tags }}
<p>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-tag meta-icon"><path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"></path><line x1="7" y1="7" x2="7" y2="7"></line></svg>
{{- range . -}}
<span class="tag"><a href="{{ "tags/" | absLangURL }}{{ . | urlize }}">{{.}}</a></span>
{{- end }}
</p>
{{- end }}
<p><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>{{ i18n "wordCount" . }}</p>
<p><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-calendar"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg>{{ dateFormat .Site.Params.dateformNumTime .Date.Local }}{{- if .Lastmod }} (last modified {{ dateFormat .Site.Params.dateformNumTime .Lastmod }}){{- end -}}</p>
{{- if and .GitInfo .Site.Params.gitUrl }}
<p><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-git-commit"><circle cx="12" cy="12" r="4"></circle><line x1="1.05" y1="12" x2="7" y2="12"></line><line x1="17.01" y1="12" x2="22.96" y2="12"></line></svg><a href="{{ .Site.Params.gitUrl -}}{{ .GitInfo.Hash }}" target="_blank" rel="noopener">{{ .GitInfo.AbbreviatedHash }}</a> @ {{ dateFormat .Site.Params.dateformNum .GitInfo.AuthorDate.Local }}</p>
{{- end }}
</footer>
</article>
{{- if .Params.toc }}
<aside id="toc">
<div class="toc-title">{{ i18n "tableOfContents" }}</div>
{{ .TableOfContents }}
</aside>
{{- end }}
<div class="post-nav thin">
{{- with .NextInSection }}
<a class="next-post" href="{{ .Permalink }}">
<span class="post-nav-label"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>&nbsp;{{ i18n "newer" }}</span><br><span>{{ .Title }}</span>
</a>
{{- end }}
{{- with .PrevInSection }}
<a class="prev-post" href="{{ .Permalink }}">
<span class="post-nav-label">{{ i18n "older" }}&nbsp;<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg></span><br><span>{{ .Title }}</span>
</a>
{{- end }}
</div>
<div id="comments" class="thin">
{{- partial "comments.html" . -}}
</div>
</main>
{{ end }}
{{ define "footer" }}
{{ partialCached "footer.html" . }}
{{ end }}

92
main.go Normal file

@ -0,0 +1,92 @@
package main
import (
"embed"
"fmt"
"io/fs"
"log"
"net/http"
"os"
"path"
"time"
)
var version = "development"
//go:embed public/*
var embeddedPublic embed.FS
// bytes of the 404.html page.
var b404 []byte
// usrIP is a good way to read the src IP this way because we trust our proxy.
// largely from: https://stackoverflow.com/a/55738279
func usrIP(r *http.Request) string {
ip := r.Header.Get("x-forwarded-for")
if ip == "" {
ip = r.Header.Get("x-real-ip")
}
if ip == "" {
ip = r.RemoteAddr
}
return ip
}
// notFound writes back 404 and the 404 page.
func notFound(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
w.Write(b404)
}
// handleNotFound allows us to override the response on e.g. 404.
// inspired by https://stackoverflow.com/a/62747667
func handleNotFound(fs http.FileSystem) http.Handler {
fileServer := http.FileServer(fs)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
p := r.URL.Path
// so as not to allow path traversals.
cleanedPath := path.Clean(p)
_, err := fs.Open(cleanedPath)
if os.IsNotExist(err) {
log.Printf("Error 404 Not Found when serving path: %s, cleaned path: %s, IP: %s",
p, cleanedPath, usrIP(r))
notFound(w, r)
return
}
fileServer.ServeHTTP(w, r)
})
}
func main() {
// TODO: ENV WHATPORT
// TODO: add /ip endpoint that returns the src IP.
f404, err := embeddedPublic.ReadFile("public/404.html")
if err != nil {
log.Fatalf("no 404.html in the folder, weird: %s", fmt.Errorf("err: %w", err))
}
b404 = f404
root, err := fs.Sub(embeddedPublic, "public")
if err != nil {
log.Fatal(err)
}
log.Printf("Starting app built from revision '%s'\n", version)
log.Print("Listening on :1314...")
// https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/
srv := http.Server{
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
Addr: ":1314",
Handler: handleNotFound(http.FS(root)),
}
err = srv.ListenAndServe()
if err != nil {
log.Fatal(err)
}
}