61 Commits

Author SHA1 Message Date
rawtaz
4e4e8c0f4c Merge pull request #364 from mattxtaz/master
Some checks failed
test / Linux Go 1.24.x (push) Has been cancelled
test / Linux (race) Go 1.25.x (push) Has been cancelled
test / Linux Go 1.25.x (push) Has been cancelled
test / lint (push) Has been cancelled
test / Analyze results (push) Has been cancelled
Remove full stop from log line to be consistent with all other log lines
2025-12-07 19:53:35 +01:00
Michael Eischer
0cc4d235d4 Merge pull request #360 from restic/dependabot/go_modules/github.com/prometheus/client_golang-1.23.2
Some checks failed
test / lint (push) Has been cancelled
test / Linux Go 1.24.x (push) Has been cancelled
test / Linux (race) Go 1.25.x (push) Has been cancelled
test / Linux Go 1.25.x (push) Has been cancelled
test / Analyze results (push) Has been cancelled
Bump github.com/prometheus/client_golang from 1.22.0 to 1.23.2
2025-12-06 21:52:41 +01:00
dependabot[bot]
f3f73ce638 Bump github.com/prometheus/client_golang from 1.22.0 to 1.23.2
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.22.0 to 1.23.2.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.22.0...v1.23.2)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-version: 1.23.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-06 20:50:57 +00:00
Michael Eischer
a4406f1456 Merge pull request #371 from restic/dependabot/go_modules/golang.org/x/crypto-0.45.0
Bump golang.org/x/crypto from 0.38.0 to 0.45.0
2025-12-06 21:48:02 +01:00
dependabot[bot]
8d9519d810 Bump golang.org/x/crypto from 0.38.0 to 0.45.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.38.0 to 0.45.0.
- [Commits](https://github.com/golang/crypto/compare/v0.38.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.45.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-06 20:33:43 +00:00
Michael Eischer
f30dd07040 Merge pull request #374 from restic/dependabot/go_modules/github.com/spf13/cobra-1.10.2
Bump github.com/spf13/cobra from 1.9.1 to 1.10.2
2025-12-06 21:32:40 +01:00
Michael Eischer
e392ec717f Merge pull request #357 from restic/dependabot/go_modules/github.com/coreos/go-systemd/v22-22.6.0
Bump github.com/coreos/go-systemd/v22 from 22.5.0 to 22.6.0
2025-12-06 21:30:59 +01:00
dependabot[bot]
6a92b43e19 Bump github.com/spf13/cobra from 1.9.1 to 1.10.2
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.9.1 to 1.10.2.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.9.1...v1.10.2)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-version: 1.10.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-06 20:30:01 +00:00
Michael Eischer
fe8f991d9c Merge pull request #373 from MichaelEischer/update-ci
Require Go 1.24 and sync CI configuration with restic
2025-12-06 21:29:16 +01:00
Michael Eischer
441efb0865 let dependabot group golang/x imports 2025-12-06 20:20:47 +01:00
Michael Eischer
9228592fe7 add changelog 2025-12-06 20:20:03 +01:00
Michael Eischer
47ebcfe5f3 bump to go 1.24 everywhere 2025-12-06 20:18:36 +01:00
Michael Eischer
c3af54dd18 sync with restic settings 2025-12-06 20:17:38 +01:00
Michael Eischer
512d7e88ee migrate to golangci-lint v2 2025-12-06 20:16:26 +01:00
Matt Xtaz
35db2868d0 Remove full stop from log line to be consistent with all other log lines 2025-12-06 19:16:09 +00:00
Michael Eischer
b3ce796ae7 update actions/checkout 2025-12-06 20:12:37 +01:00
Michael Eischer
a49c24e141 go 1.25 2025-12-06 20:12:26 +01:00
Michael Eischer
654fa16cb2 Merge pull request #359 from restic/dependabot/github_actions/actions/setup-go-6
Some checks failed
test / Linux Go 1.23.x (push) Has been cancelled
test / Linux (race) Go 1.24.x (push) Has been cancelled
test / Linux Go 1.24.x (push) Has been cancelled
test / lint (push) Has been cancelled
test / Analyze results (push) Has been cancelled
Bump actions/setup-go from 5 to 6
2025-10-04 16:51:20 +02:00
Michael Eischer
cc352125b8 Merge pull request #354 from restic/dependabot/github_actions/actions/checkout-5
Bump actions/checkout from 4 to 5
2025-10-04 16:51:00 +02:00
dependabot[bot]
822a8dca64 Bump actions/setup-go from 5 to 6
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 19:32:23 +00:00
dependabot[bot]
cffaa21bc1 Bump github.com/coreos/go-systemd/v22 from 22.5.0 to 22.6.0
Bumps [github.com/coreos/go-systemd/v22](https://github.com/coreos/go-systemd) from 22.5.0 to 22.6.0.
- [Release notes](https://github.com/coreos/go-systemd/releases)
- [Commits](https://github.com/coreos/go-systemd/compare/v22.5.0...v22.6.0)

---
updated-dependencies:
- dependency-name: github.com/coreos/go-systemd/v22
  dependency-version: 22.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-26 11:17:33 +00:00
dependabot[bot]
334ddf15ea Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 05:42:05 +00:00
Alexander Neumann
2f31e10ceb Update version for development
Some checks failed
test / Linux Go 1.23.x (push) Has been cancelled
test / Linux (race) Go 1.24.x (push) Has been cancelled
test / Linux Go 1.24.x (push) Has been cancelled
test / lint (push) Has been cancelled
test / Analyze results (push) Has been cancelled
2025-05-31 22:32:39 +02:00
Alexander Neumann
ad130de021 Generate CHANGELOG.md for 0.14.0 2025-05-31 22:21:45 +02:00
Alexander Neumann
2aaa048aba Move changelog files for 0.14.0 2025-05-31 22:21:33 +02:00
Alexander Neumann
b6ec6f45cc Update VERSION files for 0.14.0 2025-05-31 22:20:43 +02:00
rawtaz
2a77536ce5 Merge pull request #348 from restic/clarify-umask-for-group-accessible
Some checks failed
test / Linux Go 1.23.x (push) Has been cancelled
test / Linux (race) Go 1.24.x (push) Has been cancelled
test / Linux Go 1.24.x (push) Has been cancelled
test / lint (push) Has been cancelled
test / Analyze results (push) Has been cancelled
Improve description of group-accessible option
2025-05-27 20:58:05 +02:00
Michael Eischer
0adcfa2619 Improve description of group-accessible option 2025-05-27 19:43:24 +02:00
Michael Eischer
9f8bb0c87c Merge pull request #347 from restic/polish-changelogs
Some checks failed
test / Linux (race) Go 1.24.x (push) Has been cancelled
test / Linux Go 1.23.x (push) Has been cancelled
test / Linux Go 1.24.x (push) Has been cancelled
test / lint (push) Has been cancelled
test / Analyze results (push) Has been cancelled
Polish changelogs
2025-05-21 19:01:27 +02:00
Leo R. Lundgren
5faeedf050 Polish changelogs 2025-05-20 21:56:28 +02:00
Michael Eischer
7294612990 Merge pull request #346 from MichaelEischer/zip-for-windows
Some checks are pending
test / lint (push) Waiting to run
test / Analyze results (push) Blocked by required conditions
test / Linux Go 1.23.x (push) Waiting to run
test / Linux (race) Go 1.24.x (push) Waiting to run
test / Linux Go 1.24.x (push) Waiting to run
Build zip files for windows release binaries
2025-05-20 19:09:48 +02:00
Michael Eischer
25066228ee add changelog for windows zip binaries 2025-05-15 21:03:05 +02:00
Michael Eischer
72a7319fae limit build parallelism 2025-05-15 20:58:23 +02:00
Michael Eischer
df5330773f also generate zip files for windows 2025-05-15 20:58:23 +02:00
Michael Eischer
2bb4d251e2 autoformat goreleaser yaml 2025-05-15 20:58:23 +02:00
Michael Eischer
f018e99109 Merge pull request #340 from MichaelEischer/limit-htpasswd-perms
Some checks failed
test / Linux Go 1.23.x (push) Has been cancelled
test / Linux (race) Go 1.24.x (push) Has been cancelled
test / Linux Go 1.24.x (push) Has been cancelled
test / lint (push) Has been cancelled
test / Analyze results (push) Has been cancelled
Limit htpasswd perms
2025-05-15 20:20:16 +02:00
Michael Eischer
95538fe956 restrict umask of htpasswd file 2025-05-15 19:56:53 +02:00
Michael Eischer
4e6193ceee Merge pull request #339 from MichaelEischer/polish-changelogs
Some checks failed
test / Linux Go 1.23.x (push) Has been cancelled
test / Linux (race) Go 1.24.x (push) Has been cancelled
test / Linux Go 1.24.x (push) Has been cancelled
test / lint (push) Has been cancelled
test / Analyze results (push) Has been cancelled
Polish changelogs
2025-05-12 19:00:34 +02:00
Michael Eischer
4c368ae1fb polish changelogs 2025-05-12 18:50:47 +02:00
Michael Eischer
0ed9de379e Merge pull request #341 from restic/dependabot/go_modules/github.com/prometheus/client_golang-1.22.0
Bump github.com/prometheus/client_golang from 1.21.1 to 1.22.0
2025-05-12 18:47:15 +02:00
Michael Eischer
451c4831f9 Merge pull request #345 from restic/dependabot/go_modules/golang.org/x/crypto-0.38.0
Bump golang.org/x/crypto from 0.37.0 to 0.38.0
2025-05-12 18:47:00 +02:00
dependabot[bot]
1610cf6cef Bump golang.org/x/crypto from 0.37.0 to 0.38.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.37.0 to 0.38.0.
- [Commits](https://github.com/golang/crypto/compare/v0.37.0...v0.38.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 19:51:08 +00:00
dependabot[bot]
3d35116b3c Bump github.com/prometheus/client_golang from 1.21.1 to 1.22.0
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.21.1 to 1.22.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.21.1...v1.22.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-version: 1.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 20:42:16 +00:00
dependabot[bot]
eee73d3bc1 Bump golang.org/x/crypto from 0.33.0 to 0.37.0 (#337)
Some checks failed
test / Linux Go 1.23.x (push) Has been cancelled
test / Linux (race) Go 1.24.x (push) Has been cancelled
test / Linux Go 1.24.x (push) Has been cancelled
test / lint (push) Has been cancelled
test / Analyze results (push) Has been cancelled
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.33.0 to 0.37.0.
- [Commits](https://github.com/golang/crypto/compare/v0.33.0...v0.37.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 19:16:53 +00:00
Michael Eischer
df7b13e18f Merge pull request #338 from MichaelEischer/bump-go1.23
Bump minimum Go version to 1.23
2025-04-14 21:13:59 +02:00
Michael Eischer
2d3e02017b CI: add Go 1.24 and reduce diff to config used by restic 2025-04-14 21:11:57 +02:00
DarkSpir
2b6f0b39fc Hardened tls cipher suits and added option for tls min version (#315)
* handlers.go: Added parameter for TLS min version

rest-server/main.go: Added parameter handling for TLS min version

rest-server/main.go: Added crypto.tls, implemented and configured tlsConfig object

* tls min version parameter documentation

* Added changelog documentation

* README.md: Fixed typo

main.go: Added error for unknown TLS min versions

main.go: Changed CurvePreferences in TLS config to Go default

main.go: Removed handling for TLS min versions 1.0 and 1.1

Signed-off-by: darkspir <forgejo.darkspir@teemitmil.ch>

* main.go: Improved TLSMinVer parameter documentation

* README.md: Improved --tls-min-ver parameter documentation

* main.go: Changed --tls-min-ver parameter documentation again

* main.go: Added allowed versions in Error Unsupported TLS min version

* update rest-server help output in readme

---------

Signed-off-by: darkspir <forgejo.darkspir@teemitmil.ch>
Co-authored-by: Michael Eischer <michael.eischer@fau.de>
2025-04-14 19:09:57 +00:00
Michael Eischer
dbf5253ac2 Merge pull request #307 from akmet/master
Add support for proxy-based authentication
2025-04-14 21:01:11 +02:00
Michael Eischer
fa15677855 Merge pull request #334 from stemid/patch-1
Support passwords with spaces in docker container
2025-04-14 20:52:01 +02:00
Michael Eischer
19aa0845c0 create_user/delete_user: quote user and filename 2025-04-14 20:48:11 +02:00
Michael Eischer
04b52b0cee document how to use group-accessible repos with systemd (#327) 2025-04-14 20:46:20 +02:00
dependabot[bot]
f2d406ff2e Bump github.com/prometheus/client_golang from 1.20.5 to 1.21.1 (#331)
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.20.5 to 1.21.1.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.20.5...v1.21.1)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 20:45:54 +02:00
Michael Eischer
8ad7cfa60a bump minimum go version to 1.23 2025-04-14 20:44:28 +02:00
Stefan Midjich
4f17744d6c Support passwords with spaces
You must quote $2 in order to support passwords with spaces.
2025-03-13 14:40:59 +01:00
Michael Eischer
68ae5d1c0b check that proxy header is ignored if not enabled 2025-02-17 22:36:03 +01:00
Michael Eischer
0dfc772cdb document proxy auth in readme 2025-02-17 22:32:49 +01:00
akmet
b0a9a0452e Add support for proxy-based authentication 2025-02-17 22:25:25 +01:00
Massimo Lusetti
f053e33486 Add group-accessible-repos option (#308)
Some checks failed
test / Go ${{ matrix.go }} (1.22.x) (push) Has been cancelled
test / Go ${{ matrix.go }} (1.23.x) (push) Has been cancelled
test / lint (push) Has been cancelled
test / Analyze results (push) Has been cancelled
* Add group-accessible-repos option

The group-accessible-repos option will let filesystem group id
be able to access files and dir within the restic repo
Default stick with old behaviour to be owner restricted
While here make dirMode and fileMode within Options struct
private

---------

Co-authored-by: Michael Eischer <michael.eischer@fau.de>
2025-02-17 22:17:54 +01:00
Michael Eischer
10a06dcbf1 Merge pull request #325 from restic/dependabot/go_modules/golang.org/x/crypto-0.33.0
Bump golang.org/x/crypto from 0.32.0 to 0.33.0
2025-02-17 21:46:52 +01:00
dependabot[bot]
b05b44cb2c Bump golang.org/x/crypto from 0.27.0 to 0.33.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.27.0 to 0.33.0.
- [Commits](https://github.com/golang/crypto/compare/v0.27.0...v0.33.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-17 20:44:14 +00:00
Michael Eischer
a976a2145b Merge pull request #326 from restic/dependabot/go_modules/github.com/spf13/cobra-1.9.1
Bump github.com/spf13/cobra from 1.8.1 to 1.9.1
2025-02-17 21:43:11 +01:00
31 changed files with 579 additions and 217 deletions

View File

@@ -5,6 +5,10 @@ updates:
directory: "/" # Location of package manifests directory: "/" # Location of package manifests
schedule: schedule:
interval: "weekly" interval: "weekly"
groups:
golang-x-deps:
patterns:
- "golang.org/x/*"
# Dependencies listed in .github/workflows/*.yml # Dependencies listed in .github/workflows/*.yml
- package-ecosystem: "github-actions" - package-ecosystem: "github-actions"

View File

@@ -13,28 +13,40 @@ permissions:
contents: read contents: read
env: env:
latest_go: "1.23.x" latest_go: "1.25.x"
GO111MODULE: on GO111MODULE: on
jobs: jobs:
test: test:
strategy: strategy:
matrix: matrix:
go: include:
- 1.23.x - job_name: Linux
- 1.22.x go: 1.25.x
runs-on: ubuntu-latest os: ubuntu-latest
name: Go ${{ matrix.go }} check_changelog: true
- job_name: Linux (race)
go: 1.25.x
os: ubuntu-latest
test_opts: "-race"
- job_name: Linux
go: 1.24.x
os: ubuntu-latest
name: ${{ matrix.job_name }} Go ${{ matrix.go }}
runs-on: ${{ matrix.os }}
env: env:
GOPROXY: https://proxy.golang.org GOPROXY: https://proxy.golang.org
steps: steps:
- name: Check out code - name: Check out code
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Set up Go ${{ matrix.go }} - name: Set up Go ${{ matrix.go }}
uses: actions/setup-go@v5 uses: actions/setup-go@v6
with: with:
go-version: ${{ matrix.go }} go-version: ${{ matrix.go }}
@@ -46,7 +58,7 @@ jobs:
- name: Run local Tests - name: Run local Tests
run: | run: |
go test ./... go test -cover ${{matrix.test_opts}} ./...
- name: Check changelog files with calens - name: Check changelog files with calens
run: | run: |
@@ -55,6 +67,7 @@ jobs:
echo "check changelog files" echo "check changelog files"
calens calens
if: matrix.check_changelog
lint: lint:
name: lint name: lint
@@ -65,18 +78,18 @@ jobs:
checks: write checks: write
steps: steps:
- name: Check out code - name: Check out code
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Set up Go ${{ env.latest_go }} - name: Set up Go ${{ env.latest_go }}
uses: actions/setup-go@v5 uses: actions/setup-go@v6
with: with:
go-version: ${{ env.latest_go }} go-version: ${{ env.latest_go }}
- name: golangci-lint - name: golangci-lint
uses: golangci/golangci-lint-action@v6 uses: golangci/golangci-lint-action@v9
with: with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
version: v1.63.4 version: v2.4.0
args: --verbose --timeout 5m args: --verbose --timeout 5m
# only run golangci-lint for pull requests, otherwise ALL hints get # only run golangci-lint for pull requests, otherwise ALL hints get

View File

@@ -1,56 +1,47 @@
# This is the configuration for golangci-lint for the restic project. version: "2"
#
# A sample config with all settings is here:
# https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml
linters: linters:
# only enable the linters listed below # only enable the linters listed below
disable-all: true default: none
enable: enable:
- asciicheck
# ensure that http response bodies are closed
- bodyclose
- copyloopvar
# make sure all errors returned by functions are handled # make sure all errors returned by functions are handled
- errcheck - errcheck
# show how code can be simplified
- gosimple
# make sure code is formatted
- gofmt
# examine code and report suspicious constructs, such as Printf calls whose # examine code and report suspicious constructs, such as Printf calls whose
# arguments do not align with the format string # arguments do not align with the format string
- govet - govet
# consistent imports
# make sure names and comments are used according to the conventions - importas
- revive
# detect when assignments to existing variables are not used # detect when assignments to existing variables are not used
- ineffassign - ineffassign
- nolintlint
# make sure names and comments are used according to the conventions
- revive
# run static analysis and find errors # run static analysis and find errors
- staticcheck - staticcheck
# find unused variables, functions, structs, types, etc. # find unused variables, functions, structs, types, etc.
- unused - unused
exclusions:
# parse and typecheck code rules:
- typecheck - path: (.+)\.go$
text: exported (function|method|var|type|const) .* should have comment or be unexported
# ensure that http response bodies are closed - path: (.+)\.go$
- bodyclose text: don't use ALL_CAPS in Go names; use CamelCase
- path: (.+)\.go$
- importas text: "package-comments: should have a package comment"
- path: (.+)\.go$
issues: text: "redefines-builtin-id:"
# don't use the default exclude rules, this hides (among others) ignored paths:
# errors from Close() calls - third_party$
exclude-use-default: false - builtin$
- examples$
# list of things to not warn about formatters:
exclude: enable:
# revive: do not warn about missing comments for exported stuff - gofmt
- exported (function|method|var|type|const) .* should have comment or be unexported exclusions:
# revive: ignore constants in all caps paths:
- don't use ALL_CAPS in Go names; use CamelCase - third_party$
# revive: lots of packages don't have such a comment - builtin$
- "package-comments: should have a package comment" - examples$
- "redefines-builtin-id:"

View File

@@ -21,29 +21,27 @@ before:
# build a single binary # build a single binary
builds: builds:
- - id: default
# make sure everything is statically linked by disabling cgo altogether # make sure everything is statically linked by disabling cgo altogether
env: env: &build_env
- CGO_ENABLED=0 - CGO_ENABLED=0
# set the package for the main binary # set the package for the main binary
main: ./cmd/rest-server main: ./cmd/rest-server
flags: flags:
# don't include any paths to source files in the resulting binary &build_flags # don't include any paths to source files in the resulting binary
- -trimpath - -trimpath
mod_timestamp: '{{ .CommitTimestamp }}' mod_timestamp: "{{ .CommitTimestamp }}"
ldflags: ldflags: &build_ldflags # set the version variable in the main package
# set the version variable in the main package
- "-s -w -X main.version={{ .Version }}" - "-s -w -X main.version={{ .Version }}"
# list all operating systems and architectures we build binaries for # list all operating systems and architectures we build binaries for
goos: goos:
- linux - linux
- darwin - darwin
- windows
- freebsd - freebsd
- netbsd - netbsd
- openbsd - openbsd
@@ -52,7 +50,7 @@ builds:
goarch: goarch:
- amd64 - amd64
- 386 - "386"
- arm - arm
- arm64 - arm64
- mips - mips
@@ -61,23 +59,39 @@ builds:
- ppc64 - ppc64
- ppc64le - ppc64le
goarm: goarm:
- 6 - "6"
- 7 - "7"
- id: windows-only
env: *build_env
main: ./cmd/rest-server
flags: *build_flags
mod_timestamp: "{{ .CommitTimestamp }}"
ldflags: *build_ldflags
goos:
- windows
goarch:
- amd64
- "386"
- arm
- arm64
# configure the resulting archives to create # configure the resulting archives to create
archives: archives:
- - id: default
builds: [default, windows-only]
format: tar.gz
# package a directory which contains the source file # package a directory which contains the source file
wrap_in_directory: true wrap_in_directory: true
builds_info: &archive_file_info builds_info: &archive_file_info
owner: root owner: root
group: root group: root
mtime: '{{ .CommitDate }}' mtime: "{{ .CommitDate }}"
mode: 0644 mode: 0644
# add these files to all archives # add these files to all archives
files: files: &archive_files
- src: LICENSE - src: LICENSE
dst: LICENSE dst: LICENSE
info: *archive_file_info info: *archive_file_info
@@ -88,13 +102,20 @@ archives:
dst: CHANGELOG.md dst: CHANGELOG.md
info: *archive_file_info info: *archive_file_info
- id: windows-only
builds: [windows-only]
formats: [zip]
wrap_in_directory: true
builds_info: *archive_file_info
files: *archive_files
# also build an archive of the source code # also build an archive of the source code
source: source:
enabled: true enabled: true
# build a file containing the SHA256 hashes # build a file containing the SHA256 hashes
checksum: checksum:
name_template: 'SHA256SUMS' name_template: "SHA256SUMS"
# sign the checksum file # sign the checksum file
signs: signs:
@@ -128,7 +149,7 @@ dockers:
- docker/entrypoint.sh - docker/entrypoint.sh
- image_templates: - image_templates:
- restic/rest-server:{{ .Version }}-i386 - restic/rest-server:{{ .Version }}-i386
goarch: 386 goarch: "386"
build_flag_templates: build_flag_templates:
- "--platform=linux/386" - "--platform=linux/386"
- "--pull" - "--pull"
@@ -204,21 +225,20 @@ dockers:
dockerfile: "Dockerfile.goreleaser" dockerfile: "Dockerfile.goreleaser"
extra_files: *extra_files extra_files: *extra_files
docker_manifests: docker_manifests:
- name_template: "restic/rest-server:{{ .Version }}" - name_template: "restic/rest-server:{{ .Version }}"
image_templates: image_templates:
- "restic/rest-server:{{ .Version }}-amd64" - "restic/rest-server:{{ .Version }}-amd64"
- "restic/rest-server:{{ .Version }}-i386" - "restic/rest-server:{{ .Version }}-i386"
- "restic/rest-server:{{ .Version }}-arm32v6" - "restic/rest-server:{{ .Version }}-arm32v6"
- "restic/rest-server:{{ .Version }}-arm32v7" - "restic/rest-server:{{ .Version }}-arm32v7"
- "restic/rest-server:{{ .Version }}-arm64v8" - "restic/rest-server:{{ .Version }}-arm64v8"
- "restic/rest-server:{{ .Version }}-ppc64le" - "restic/rest-server:{{ .Version }}-ppc64le"
- name_template: "restic/rest-server:latest" - name_template: "restic/rest-server:latest"
image_templates: image_templates:
- "restic/rest-server:{{ .Version }}-amd64" - "restic/rest-server:{{ .Version }}-amd64"
- "restic/rest-server:{{ .Version }}-i386" - "restic/rest-server:{{ .Version }}-i386"
- "restic/rest-server:{{ .Version }}-arm32v6" - "restic/rest-server:{{ .Version }}-arm32v6"
- "restic/rest-server:{{ .Version }}-arm32v7" - "restic/rest-server:{{ .Version }}-arm32v7"
- "restic/rest-server:{{ .Version }}-arm64v8" - "restic/rest-server:{{ .Version }}-arm64v8"
- "restic/rest-server:{{ .Version }}-ppc64le" - "restic/rest-server:{{ .Version }}-ppc64le"

View File

@@ -1,3 +1,98 @@
Changelog for rest-server 0.14.0 (2025-05-31)
============================================
The following sections list the changes in rest-server 0.14.0 relevant
to users. The changes are ordered by importance.
Summary
-------
* Sec #318: Fix world-readable permissions on new `.htpasswd` files
* Chg #322: Update dependencies and require Go 1.23 or newer
* Enh #174: Support proxy-based authentication
* Enh #189: Support group accessible repositories
* Enh #295: Output status of append-only mode on startup
* Enh #315: Hardened tls settings
* Enh #321: Add zip archive format for Windows releases
Details
-------
* Security #318: Fix world-readable permissions on new `.htpasswd` files
On startup the rest-server Docker container creates an empty `.htpasswd` file if
none exists yet. This file was world-readable by default, which can be a
security risk, even though the file only contains hashed passwords.
This has been fixed such that new `.htpasswd` files are no longer
world-readabble.
The permissions of existing `.htpasswd` files must be manually changed if
relevant in your setup.
https://github.com/restic/rest-server/issues/318
https://github.com/restic/rest-server/pull/340
* Change #322: Update dependencies and require Go 1.23 or newer
All dependencies have been updated. Rest-server now requires Go 1.23 or newer to
build.
This also disables support for TLS versions older than TLS 1.2. On Windows,
rest-server now requires at least Windows 10 or Windows Server 2016. On macOS,
rest-server now requires at least macOS 11 Big Sur.
https://github.com/restic/rest-server/pull/322
https://github.com/restic/rest-server/pull/338
* Enhancement #174: Support proxy-based authentication
Rest-server now supports authentication via HTTP proxy headers. This feature can
be enabled by specifying the username header using the `--proxy-auth-username`
option (e.g., `--proxy-auth-username=X-Forwarded-User`).
When enabled, the server authenticates users based on the specified header and
disables Basic Auth. Note that proxy authentication is disabled when `--no-auth`
is set.
https://github.com/restic/rest-server/issues/174
https://github.com/restic/rest-server/pull/307
* Enhancement #189: Support group accessible repositories
Rest-server now supports making repositories accessible to the filesystem group
by setting the `--group-accessible-repos` option. Note that permissions of
existing files are not modified. To allow the group to read and write file, use
a umask of `007`. To only grant read access use `027`. To make an existing
repository group-accessible, use `chmod -R g+rwX /path/to/repo`.
https://github.com/restic/rest-server/issues/189
https://github.com/restic/rest-server/pull/308
* Enhancement #295: Output status of append-only mode on startup
Rest-server now displays the status of append-only mode during startup.
https://github.com/restic/rest-server/pull/295
* Enhancement #315: Hardened tls settings
Rest-server now uses a secure TLS cipher suite set by default. The minimum TLS
version is now TLS 1.2 and can be further increased using the new
`--tls-min-ver` option, allowing users to enforce stricter security
requirements.
https://github.com/restic/rest-server/pull/315
* Enhancement #321: Add zip archive format for Windows releases
Windows users can now download rest-server binaries in zip archive format (.zip)
in addition to the existing tar.gz archives.
https://github.com/restic/rest-server/issues/321
https://github.com/restic/rest-server/pull/346
Changelog for rest-server 0.13.0 (2024-07-26) Changelog for rest-server 0.13.0 (2024-07-26)
============================================ ============================================

View File

@@ -11,7 +11,7 @@ Rest Server is a high performance HTTP server that implements restic's [REST bac
## Requirements ## Requirements
Rest Server requires Go 1.22 or higher to build. The only tested compiler is the official Go compiler. Rest Server requires Go 1.24 or higher to build. The only tested compiler is the official Go compiler.
The required version of restic backup client to use with `rest-server` is [v0.7.1](https://github.com/restic/restic/releases/tag/v0.7.1) or higher. The required version of restic backup client to use with `rest-server` is [v0.7.1](https://github.com/restic/restic/releases/tag/v0.7.1) or higher.
@@ -32,24 +32,27 @@ Usage:
rest-server [flags] rest-server [flags]
Flags: Flags:
--append-only enable append only mode --append-only enable append only mode
--cpu-profile string write CPU profile to file --cpu-profile string write CPU profile to file
--debug output debug messages --debug output debug messages
-h, --help help for rest-server --group-accessible-repos let filesystem group be able to access repo files
--htpasswd-file string location of .htpasswd file (default: "<data directory>/.htpasswd") -h, --help help for rest-server
--listen string listen address (default ":8000") --htpasswd-file string location of .htpasswd file (default: "<data directory>/.htpasswd)"
--log filename write HTTP requests in the combined log format to the specified filename --listen string listen address (default ":8000")
--max-size int the maximum size of the repository in bytes --log filename write HTTP requests in the combined log format to the specified filename (use "-" for logging to stdout)
--no-auth disable .htpasswd authentication --max-size int the maximum size of the repository in bytes
--no-verify-upload do not verify the integrity of uploaded data. DO NOT enable unless the rest-server runs on a very low-power device --no-auth disable .htpasswd authentication
--path string data directory (default "/tmp/restic") --no-verify-upload do not verify the integrity of uploaded data. DO NOT enable unless the rest-server runs on a very low-power device
--private-repos users can only access their private repo --path string data directory (default "/tmp/restic")
--prometheus enable Prometheus metrics --private-repos users can only access their private repo
--prometheus-no-auth disable auth for Prometheus /metrics endpoint --prometheus enable Prometheus metrics
--tls turn on TLS support --prometheus-no-auth disable auth for Prometheus /metrics endpoint
--tls-cert string TLS certificate path --proxy-auth-username string specifies the HTTP header containing the username for proxy-based authentication
--tls-key string TLS key path --tls turn on TLS support
-v, --version version for rest-server --tls-cert string TLS certificate path
--tls-key string TLS key path
--tls-min-ver string TLS min version, one of (1.2|1.3) (default "1.2")
-v, --version version for rest-server
``` ```
By default the server persists backup data in the OS temporary directory (`/tmp/restic` on Linux/BSD and others, in `%TEMP%\\restic` in Windows, etc). **If `rest-server` is launched using the default path, all backups will be lost**. To start the server with a custom persistence directory and with authentication disabled: By default the server persists backup data in the OS temporary directory (`/tmp/restic` on Linux/BSD and others, in `%TEMP%\\restic` in Windows, etc). **If `rest-server` is launched using the default path, all backups will be lost**. To start the server with a custom persistence directory and with authentication disabled:
@@ -68,7 +71,7 @@ If you want to disable authentication, you must add the `--no-auth` flag. If thi
NOTE: In older versions of rest-server (up to 0.9.7), this flag does not exist and the server disables authentication if `.htpasswd` is missing or cannot be opened. NOTE: In older versions of rest-server (up to 0.9.7), this flag does not exist and the server disables authentication if `.htpasswd` is missing or cannot be opened.
By default the server uses HTTP protocol. This is not very secure since with Basic Authentication, user name and passwords will be sent in clear text in every request. In order to enable TLS support just add the `--tls` argument and add a private and public key at the root of your persistence directory. You may also specify private and public keys by `--tls-cert` and `--tls-key`. By default the server uses HTTP protocol. This is not very secure since with Basic Authentication, user name and passwords will be sent in clear text in every request. In order to enable TLS support just add the `--tls` argument and add a private and public key at the root of your persistence directory. You may also specify private and public keys by `--tls-cert` and `--tls-key` and set the minimum TLS version to 1.3 using `--tls-min-ver 1.3`.
Signed certificate is normally required by the restic backend, but if you just want to test the feature you can generate password-less unsigned keys with the following command: Signed certificate is normally required by the restic backend, but if you just want to test the feature you can generate password-less unsigned keys with the following command:
@@ -139,6 +142,16 @@ docker exec -it rest_server create_user myuser mypassword
docker exec -it rest_server delete_user myuser docker exec -it rest_server delete_user myuser
``` ```
## Proxy Authentication
See above for no authentication (`--no-auth`) and basic authentication.
To delegate authentication to a proxy, use the `--proxy-auth-username` flag. The specified header name, for example `X-Forwarded-User`,
must be present in the request headers and specifies the username. Basic authentication is disabled when this flag is set.
Warning: rest-server trusts the username in the header. It is the responsibility of the proxy
to ensure that the username is correct and cannot be forged by an attacker.
## Prometheus support and Grafana dashboard ## Prometheus support and Grafana dashboard
@@ -147,6 +160,10 @@ The server can be started with `--prometheus` to expose [Prometheus](https://pro
This repository contains an example full stack Docker Compose setup with a Grafana dashboard in [examples/compose-with-grafana/](examples/compose-with-grafana/). This repository contains an example full stack Docker Compose setup with a Grafana dashboard in [examples/compose-with-grafana/](examples/compose-with-grafana/).
## Group-accessible Repositories
Rest-server supports making repositories accessible to the filesystem group by setting the `--group-accessible-repos` option. Note that permissions of existing files are not modified. To allow the group to read and write file, use a umask of `007`. To only grant read access use `027`. To make an existing repository group-accessible, use `chmod -R g+rwX /path/to/repo`.
## Why use Rest Server? ## Why use Rest Server?
Compared to the SFTP backend, the REST backend has better performance, especially so if you can skip additional crypto overhead by using plain HTTP transport (restic already properly encrypts all data it sends, so using HTTPS is mostly about authentication). Compared to the SFTP backend, the REST backend has better performance, especially so if you can skip additional crypto overhead by using plain HTTP transport (restic already properly encrypts all data it sends, so using HTTPS is mostly about authentication).

View File

@@ -34,7 +34,7 @@
use another config file): use another config file):
goreleaser \ goreleaser \
release \ release --parallelism 4 \
--release-notes <(calens --template changelog/CHANGELOG-GitHub.tmpl --version "${VERSION}") --release-notes <(calens --template changelog/CHANGELOG-GitHub.tmpl --version "${VERSION}")
7. Set a new version in `main.go` and commit the result: 7. Set a new version in `main.go` and commit the result:

View File

@@ -1 +1 @@
0.13.0 0.14.0

View File

@@ -58,7 +58,7 @@ var config = Config{
Namespace: "github.com/restic/rest-server", // subdir of GOPATH, e.g. "github.com/foo/bar" Namespace: "github.com/restic/rest-server", // subdir of GOPATH, e.g. "github.com/foo/bar"
Main: "github.com/restic/rest-server/cmd/rest-server", // package name for the main package Main: "github.com/restic/rest-server/cmd/rest-server", // package name for the main package
Tests: []string{"./..."}, // tests to run Tests: []string{"./..."}, // tests to run
MinVersion: GoVersion{Major: 1, Minor: 22, Patch: 0}, // minimum Go version supported MinVersion: GoVersion{Major: 1, Minor: 24, Patch: 0}, // minimum Go version supported
} }
// Config configures the build. // Config configures the build.

View File

@@ -0,0 +1,10 @@
Enhancement: Support group accessible repositories
Rest-server now supports making repositories accessible to the filesystem group
by setting the `--group-accessible-repos` option. Note that permissions of
existing files are not modified. To allow the group to read and write file,
use a umask of `007`. To only grant read access use `027`. To make an existing
repository group-accessible, use `chmod -R g+rwX /path/to/repo`.
https://github.com/restic/rest-server/issues/189
https://github.com/restic/rest-server/pull/308

View File

@@ -0,0 +1,13 @@
Security: Fix world-readable permissions on new `.htpasswd` files
On startup the rest-server Docker container creates an empty `.htpasswd` file
if none exists yet. This file was world-readable by default, which can be
a security risk, even though the file only contains hashed passwords.
This has been fixed such that new `.htpasswd` files are no longer world-readabble.
The permissions of existing `.htpasswd` files must be manually changed if
relevant in your setup.
https://github.com/restic/rest-server/issues/318
https://github.com/restic/rest-server/pull/340

View File

@@ -0,0 +1,7 @@
Enhancement: Add zip archive format for Windows releases
Windows users can now download rest-server binaries in zip archive format (.zip)
in addition to the existing tar.gz archives.
https://github.com/restic/rest-server/issues/321
https://github.com/restic/rest-server/pull/346

View File

@@ -0,0 +1,5 @@
Enhancement: Output status of append-only mode on startup
Rest-server now displays the status of append-only mode during startup.
https://github.com/restic/rest-server/pull/295

View File

@@ -0,0 +1,12 @@
Enhancement: Support proxy-based authentication
Rest-server now supports authentication via HTTP proxy headers. This feature can
be enabled by specifying the username header using the `--proxy-auth-username`
option (e.g., `--proxy-auth-username=X-Forwarded-User`).
When enabled, the server authenticates users based on the specified header and
disables Basic Auth. Note that proxy authentication is disabled when `--no-auth`
is set.
https://github.com/restic/rest-server/issues/174
https://github.com/restic/rest-server/pull/307

View File

@@ -0,0 +1,7 @@
Enhancement: Hardened tls settings
Rest-server now uses a secure TLS cipher suite set by default. The minimum TLS
version is now TLS 1.2 and can be further increased using the new `--tls-min-ver`
option, allowing users to enforce stricter security requirements.
https://github.com/restic/rest-server/pull/315

View File

@@ -0,0 +1,11 @@
Change: Update dependencies and require Go 1.23 or newer
All dependencies have been updated. Rest-server now requires Go 1.23 or newer
to build.
This also disables support for TLS versions older than TLS 1.2. On Windows,
rest-server now requires at least Windows 10 or Windows Server 2016. On macOS,
rest-server now requires at least macOS 11 Big Sur.
https://github.com/restic/rest-server/pull/322
https://github.com/restic/rest-server/pull/338

View File

@@ -1,5 +0,0 @@
Enhancement: Output status of append only mode on startup
Rest-server now outputs whether append only mode has been enabled on startup.
https://github.com/restic/rest-server/pull/295

View File

@@ -1,9 +0,0 @@
Change: Update dependencies and require Go 1.22 or newer
We have updated all dependencies. Since some libraries require newer Go standard
library features, support for Go 1.18 to 1.21 has been dropped, which means
that rest-server now requires at least Go 1.22 to build.
This also disables support for TLS versions older than TLS 1.2.
https://github.com/restic/rest-server/pull/322

View File

@@ -0,0 +1,6 @@
Change: Update dependencies and require Go 1.24 or newer
All dependencies have been updated. Rest-server now requires Go 1.24 or newer
to build.
https://github.com/restic/rest-server/pull/373

View File

@@ -2,6 +2,7 @@ package main
import ( import (
"context" "context"
"crypto/tls"
"errors" "errors"
"fmt" "fmt"
"log" "log"
@@ -45,8 +46,9 @@ func newRestServerApp() *restServerApp {
Version: fmt.Sprintf("rest-server %s compiled with %v on %v/%v\n", version, runtime.Version(), runtime.GOOS, runtime.GOARCH), Version: fmt.Sprintf("rest-server %s compiled with %v on %v/%v\n", version, runtime.Version(), runtime.GOOS, runtime.GOARCH),
}, },
Server: restserver.Server{ Server: restserver.Server{
Path: filepath.Join(os.TempDir(), "restic"), Path: filepath.Join(os.TempDir(), "restic"),
Listen: ":8000", Listen: ":8000",
TLSMinVer: "1.2",
}, },
} }
rv.CmdRoot.RunE = rv.runRoot rv.CmdRoot.RunE = rv.runRoot
@@ -61,19 +63,22 @@ func newRestServerApp() *restServerApp {
flags.BoolVar(&rv.Server.TLS, "tls", rv.Server.TLS, "turn on TLS support") flags.BoolVar(&rv.Server.TLS, "tls", rv.Server.TLS, "turn on TLS support")
flags.StringVar(&rv.Server.TLSCert, "tls-cert", rv.Server.TLSCert, "TLS certificate path") flags.StringVar(&rv.Server.TLSCert, "tls-cert", rv.Server.TLSCert, "TLS certificate path")
flags.StringVar(&rv.Server.TLSKey, "tls-key", rv.Server.TLSKey, "TLS key path") flags.StringVar(&rv.Server.TLSKey, "tls-key", rv.Server.TLSKey, "TLS key path")
flags.BoolVar(&rv.Server.NoAuth, "no-auth", rv.Server.NoAuth, "disable .htpasswd authentication") flags.StringVar(&rv.Server.TLSMinVer, "tls-min-ver", rv.Server.TLSMinVer, "TLS min version, one of (1.2|1.3)")
flags.BoolVar(&rv.Server.NoAuth, "no-auth", rv.Server.NoAuth, "disable authentication")
flags.StringVar(&rv.Server.HtpasswdPath, "htpasswd-file", rv.Server.HtpasswdPath, "location of .htpasswd file (default: \"<data directory>/.htpasswd)\"") flags.StringVar(&rv.Server.HtpasswdPath, "htpasswd-file", rv.Server.HtpasswdPath, "location of .htpasswd file (default: \"<data directory>/.htpasswd)\"")
flags.StringVar(&rv.Server.ProxyAuthUsername, "proxy-auth-username", rv.Server.ProxyAuthUsername, "specifies the HTTP header containing the username for proxy-based authentication")
flags.BoolVar(&rv.Server.NoVerifyUpload, "no-verify-upload", rv.Server.NoVerifyUpload, flags.BoolVar(&rv.Server.NoVerifyUpload, "no-verify-upload", rv.Server.NoVerifyUpload,
"do not verify the integrity of uploaded data. DO NOT enable unless the rest-server runs on a very low-power device") "do not verify the integrity of uploaded data. DO NOT enable unless the rest-server runs on a very low-power device")
flags.BoolVar(&rv.Server.AppendOnly, "append-only", rv.Server.AppendOnly, "enable append only mode") flags.BoolVar(&rv.Server.AppendOnly, "append-only", rv.Server.AppendOnly, "enable append only mode")
flags.BoolVar(&rv.Server.PrivateRepos, "private-repos", rv.Server.PrivateRepos, "users can only access their private repo") flags.BoolVar(&rv.Server.PrivateRepos, "private-repos", rv.Server.PrivateRepos, "users can only access their private repo")
flags.BoolVar(&rv.Server.Prometheus, "prometheus", rv.Server.Prometheus, "enable Prometheus metrics") flags.BoolVar(&rv.Server.Prometheus, "prometheus", rv.Server.Prometheus, "enable Prometheus metrics")
flags.BoolVar(&rv.Server.PrometheusNoAuth, "prometheus-no-auth", rv.Server.PrometheusNoAuth, "disable auth for Prometheus /metrics endpoint") flags.BoolVar(&rv.Server.PrometheusNoAuth, "prometheus-no-auth", rv.Server.PrometheusNoAuth, "disable auth for Prometheus /metrics endpoint")
flags.BoolVar(&rv.Server.GroupAccessibleRepos, "group-accessible-repos", rv.Server.GroupAccessibleRepos, "let filesystem group be able to access repo files")
return rv return rv
} }
var version = "0.13.0" var version = "0.14.0-dev"
func (app *restServerApp) tlsSettings() (bool, string, string, error) { func (app *restServerApp) tlsSettings() (bool, string, string, error) {
var key, cert string var key, cert string
@@ -129,7 +134,11 @@ func (app *restServerApp) runRoot(_ *cobra.Command, _ []string) error {
if app.Server.NoAuth { if app.Server.NoAuth {
log.Println("Authentication disabled") log.Println("Authentication disabled")
} else { } else {
log.Println("Authentication enabled") if app.Server.ProxyAuthUsername == "" {
log.Println("Authentication enabled")
} else {
log.Println("Proxy Authentication enabled")
}
} }
handler, err := restserver.NewHandler(&app.Server) handler, err := restserver.NewHandler(&app.Server)
@@ -149,6 +158,12 @@ func (app *restServerApp) runRoot(_ *cobra.Command, _ []string) error {
log.Println("Private repositories disabled") log.Println("Private repositories disabled")
} }
if app.Server.GroupAccessibleRepos {
log.Println("Group accessible repos enabled")
} else {
log.Println("Group accessible repos disabled")
}
enabledTLS, privateKey, publicKey, err := app.tlsSettings() enabledTLS, privateKey, publicKey, err := app.tlsSettings()
if err != nil { if err != nil {
return err return err
@@ -164,8 +179,29 @@ func (app *restServerApp) runRoot(_ *cobra.Command, _ []string) error {
app.listenerAddress = listener.Addr() app.listenerAddress = listener.Addr()
app.listenerAddressMu.Unlock() app.listenerAddressMu.Unlock()
tlscfg := &tls.Config{
MinVersion: tls.VersionTLS12,
CipherSuites: []uint16{
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
},
}
switch app.Server.TLSMinVer {
case "1.2":
tlscfg.MinVersion = tls.VersionTLS12
case "1.3":
tlscfg.MinVersion = tls.VersionTLS13
default:
return fmt.Errorf("unsupported TLS min version: %s. Allowed versions are 1.2 or 1.3", app.Server.TLSMinVer)
}
srv := &http.Server{ srv := &http.Server{
Handler: handler, Handler: handler,
TLSConfig: tlscfg,
} }
// run server in background // run server in background

View File

@@ -118,6 +118,12 @@ func TestGetHandler(t *testing.T) {
t.Errorf("NoAuth=true: expected no error, got %v", err) t.Errorf("NoAuth=true: expected no error, got %v", err)
} }
// With NoAuth = false, no .htpasswd and ProxyAuth = X-Remote-User
_, err = getHandler(&restserver.Server{Path: dir, ProxyAuthUsername: "X-Remote-User"})
if err != nil {
t.Errorf("NoAuth=false, ProxyAuthUsername = X-Remote-User: expected no error, got %v", err)
}
// With NoAuth = false and custom .htpasswd // With NoAuth = false and custom .htpasswd
htpFile, err := os.CreateTemp(dir, "custom") htpFile, err := os.CreateTemp(dir, "custom")
if err != nil { if err != nil {

View File

@@ -9,8 +9,8 @@ fi
if [ -z "$2" ]; then if [ -z "$2" ]; then
# password from prompt # password from prompt
htpasswd -B $PASSWORD_FILE $1 htpasswd -B "$PASSWORD_FILE" "$1"
else else
# read password from command line # read password from command line
htpasswd -B -b $PASSWORD_FILE $1 $2 htpasswd -B -b "$PASSWORD_FILE" "$1" "$2"
fi fi

View File

@@ -5,4 +5,4 @@ if [ -z "$1" ]; then
exit 1 exit 1
fi fi
htpasswd -D $PASSWORD_FILE $1 htpasswd -D "$PASSWORD_FILE" "$1"

View File

@@ -6,7 +6,7 @@ if [ -n "$DISABLE_AUTHENTICATION" ]; then
OPTIONS="--no-auth $OPTIONS" OPTIONS="--no-auth $OPTIONS"
else else
if [ ! -f "$PASSWORD_FILE" ]; then if [ ! -f "$PASSWORD_FILE" ]; then
touch "$PASSWORD_FILE" ( umask 027 && touch "$PASSWORD_FILE" )
fi fi
if [ ! -s "$PASSWORD_FILE" ]; then if [ ! -s "$PASSWORD_FILE" ]; then

View File

@@ -26,8 +26,10 @@ RestartSec=5
# The following line must be customised to your individual requirements. # The following line must be customised to your individual requirements.
ReadWritePaths=/path/to/backups ReadWritePaths=/path/to/backups
# Makes created files group-readable, but inaccessible by others # Files in the data repository are only user accessible by default. Default to
UMask=027 # `UMask=077` for consistency. To make created files group-readable, set to
# `UMask=007` and pass `--group-accessible-repos` to rest-server via `ExecStart`.
UMask=077
# If your system doesn't support all of the features below (e.g. because of # If your system doesn't support all of the features below (e.g. because of
# the use of an older version of systemd), you may wish to comment-out # the use of an older version of systemd), you may wish to comment-out

25
go.mod
View File

@@ -1,15 +1,15 @@
module github.com/restic/rest-server module github.com/restic/rest-server
go 1.22 go 1.24.0
require ( require (
github.com/coreos/go-systemd/v22 v22.5.0 github.com/coreos/go-systemd/v22 v22.6.0
github.com/gorilla/handlers v1.5.2 github.com/gorilla/handlers v1.5.2
github.com/minio/sha256-simd v1.0.1 github.com/minio/sha256-simd v1.0.1
github.com/miolini/datacounter v1.0.3 github.com/miolini/datacounter v1.0.3
github.com/prometheus/client_golang v1.20.5 github.com/prometheus/client_golang v1.23.2
github.com/spf13/cobra v1.9.1 github.com/spf13/cobra v1.10.2
golang.org/x/crypto v0.32.0 golang.org/x/crypto v0.45.0
) )
require ( require (
@@ -17,13 +17,14 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/common v0.66.1 // indirect
github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/procfs v0.16.1 // indirect
github.com/spf13/pflag v1.0.6 // indirect github.com/spf13/pflag v1.0.9 // indirect
golang.org/x/sys v0.30.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect
google.golang.org/protobuf v1.36.5 // indirect golang.org/x/sys v0.38.0 // indirect
google.golang.org/protobuf v1.36.8 // indirect
) )

67
go.sum
View File

@@ -2,24 +2,28 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
@@ -30,27 +34,36 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -15,23 +15,26 @@ import (
// Server encapsulates the rest-server's settings and repo management logic // Server encapsulates the rest-server's settings and repo management logic
type Server struct { type Server struct {
Path string Path string
HtpasswdPath string HtpasswdPath string
Listen string Listen string
Log string Log string
CPUProfile string CPUProfile string
TLSKey string TLSKey string
TLSCert string TLSCert string
TLS bool TLSMinVer string
NoAuth bool TLS bool
AppendOnly bool NoAuth bool
PrivateRepos bool ProxyAuthUsername string
Prometheus bool AppendOnly bool
PrometheusNoAuth bool PrivateRepos bool
Debug bool Prometheus bool
MaxRepoSize int64 PrometheusNoAuth bool
PanicOnError bool Debug bool
NoVerifyUpload bool MaxRepoSize int64
PanicOnError bool
NoVerifyUpload bool
GroupAccessibleRepos bool
htpasswdFile *HtpasswdFile htpasswdFile *HtpasswdFile
quotaManager *quota.Manager quotaManager *quota.Manager
@@ -88,12 +91,13 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Pass the request to the repo.Handler // Pass the request to the repo.Handler
opt := repo.Options{ opt := repo.Options{
AppendOnly: s.AppendOnly, AppendOnly: s.AppendOnly,
Debug: s.Debug, Debug: s.Debug,
QuotaManager: s.quotaManager, // may be nil QuotaManager: s.quotaManager, // may be nil
PanicOnError: s.PanicOnError, PanicOnError: s.PanicOnError,
NoVerifyUpload: s.NoVerifyUpload, NoVerifyUpload: s.NoVerifyUpload,
FsyncWarning: &s.fsyncWarning, FsyncWarning: &s.fsyncWarning,
GroupAccessible: s.GroupAccessibleRepos,
} }
if s.Prometheus { if s.Prometheus {
opt.BlobMetricFunc = makeBlobMetricFunc(username, folderPath) opt.BlobMetricFunc = makeBlobMetricFunc(username, folderPath)

17
mux.go
View File

@@ -41,10 +41,17 @@ func (s *Server) checkAuth(r *http.Request) (username string, ok bool) {
if s.NoAuth { if s.NoAuth {
return username, true return username, true
} }
var password string if s.ProxyAuthUsername != "" {
username, password, ok = r.BasicAuth() username = r.Header.Get(s.ProxyAuthUsername)
if !ok || !s.htpasswdFile.Validate(username, password) { if username == "" {
return "", false return "", false
}
} else {
var password string
username, password, ok = r.BasicAuth()
if !ok || !s.htpasswdFile.Validate(username, password) {
return "", false
}
} }
return username, true return username, true
} }
@@ -66,7 +73,7 @@ func (s *Server) wrapMetricsAuth(f http.HandlerFunc) http.HandlerFunc {
// NewHandler returns the master HTTP multiplexer/router. // NewHandler returns the master HTTP multiplexer/router.
func NewHandler(server *Server) (http.Handler, error) { func NewHandler(server *Server) (http.Handler, error) {
if !server.NoAuth { if !server.NoAuth && server.ProxyAuthUsername == "" {
var err error var err error
if server.HtpasswdPath == "" { if server.HtpasswdPath == "" {
server.HtpasswdPath = filepath.Join(server.Path, ".htpasswd") server.HtpasswdPath = filepath.Join(server.Path, ".htpasswd")

80
mux_test.go Normal file
View File

@@ -0,0 +1,80 @@
package restserver
import (
"net/http/httptest"
"testing"
)
func TestCheckAuth(t *testing.T) {
tests := []struct {
name string
server *Server
requestHeaders map[string]string
basicAuth bool
basicUser string
basicPassword string
expectedUser string
expectedOk bool
}{
{
name: "NoAuth enabled",
server: &Server{
NoAuth: true,
},
expectedOk: true,
},
{
name: "Proxy Auth successful",
server: &Server{
ProxyAuthUsername: "X-Remote-User",
},
requestHeaders: map[string]string{
"X-Remote-User": "restic",
},
expectedUser: "restic",
expectedOk: true,
},
{
name: "Proxy Auth empty header",
server: &Server{
ProxyAuthUsername: "X-Remote-User",
},
requestHeaders: map[string]string{
"X-Remote-User": "",
},
expectedOk: false,
},
{
name: "Proxy Auth missing header",
server: &Server{
ProxyAuthUsername: "X-Remote-User",
},
expectedOk: false,
},
{
name: "Proxy Auth send but not enabled",
server: &Server{},
requestHeaders: map[string]string{
"X-Remote-User": "restic",
},
expectedOk: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest("GET", "/", nil)
for header, value := range tt.requestHeaders {
req.Header.Set(header, value)
}
if tt.basicAuth {
req.SetBasicAuth(tt.basicUser, tt.basicPassword)
}
username, ok := tt.server.checkAuth(req)
if username != tt.expectedUser || ok != tt.expectedOk {
t.Errorf("expected (%v, %v), got (%v, %v)", tt.expectedUser, tt.expectedOk, username, ok)
}
})
}
}

View File

@@ -28,8 +28,6 @@ import (
type Options struct { type Options struct {
AppendOnly bool // if set, delete actions are not allowed AppendOnly bool // if set, delete actions are not allowed
Debug bool Debug bool
DirMode os.FileMode
FileMode os.FileMode
NoVerifyUpload bool NoVerifyUpload bool
// If set, we will panic when an internal server error happens. This // If set, we will panic when an internal server error happens. This
@@ -39,6 +37,13 @@ type Options struct {
BlobMetricFunc BlobMetricFunc BlobMetricFunc BlobMetricFunc
QuotaManager *quota.Manager QuotaManager *quota.Manager
FsyncWarning *sync.Once FsyncWarning *sync.Once
// If set makes files group accessible
GroupAccessible bool
// Defaults dir and file mode
dirMode os.FileMode
fileMode os.FileMode
} }
// DefaultDirMode is the file mode used for directory creation if not // DefaultDirMode is the file mode used for directory creation if not
@@ -49,6 +54,14 @@ const DefaultDirMode os.FileMode = 0700
// overridden in the Options // overridden in the Options
const DefaultFileMode os.FileMode = 0600 const DefaultFileMode os.FileMode = 0600
// GroupAccessibleDirMode is the file mode used for directory creation when
// group access is enabled
const GroupAccessibleDirMode os.FileMode = 0770
// GroupAccessibleFileMode is the file mode used for file creation when
// group access is enabled
const GroupAccessibleFileMode os.FileMode = 0660
// New creates a new Handler for a single Restic backup repo. // New creates a new Handler for a single Restic backup repo.
// path is the full filesystem path to this repo directory. // path is the full filesystem path to this repo directory.
// opt is a set of options. // opt is a set of options.
@@ -56,12 +69,15 @@ func New(path string, opt Options) (*Handler, error) {
if path == "" { if path == "" {
return nil, fmt.Errorf("path is required") return nil, fmt.Errorf("path is required")
} }
if opt.DirMode == 0 {
opt.DirMode = DefaultDirMode opt.dirMode = DefaultDirMode
} opt.fileMode = DefaultFileMode
if opt.FileMode == 0 {
opt.FileMode = DefaultFileMode if opt.GroupAccessible {
opt.dirMode = GroupAccessibleDirMode
opt.fileMode = GroupAccessibleFileMode
} }
h := Handler{ h := Handler{
path: path, path: path,
opt: opt, opt: opt,
@@ -288,7 +304,7 @@ func (h *Handler) saveConfig(w http.ResponseWriter, r *http.Request) {
} }
cfg := h.getSubPath("config") cfg := h.getSubPath("config")
f, err := os.OpenFile(cfg, os.O_CREATE|os.O_WRONLY|os.O_EXCL, h.opt.FileMode) f, err := os.OpenFile(cfg, os.O_CREATE|os.O_WRONLY|os.O_EXCL, h.opt.fileMode)
if err != nil && os.IsExist(err) { if err != nil && os.IsExist(err) {
if h.opt.Debug { if h.opt.Debug {
log.Print(err) log.Print(err)
@@ -554,15 +570,15 @@ func (h *Handler) saveBlob(w http.ResponseWriter, r *http.Request) {
} }
tmpFn := filepath.Join(filepath.Dir(path), objectID+".rest-server-temp") tmpFn := filepath.Join(filepath.Dir(path), objectID+".rest-server-temp")
tf, err := tempFile(tmpFn, h.opt.FileMode) tf, err := tempFile(tmpFn, h.opt.fileMode)
if os.IsNotExist(err) { if os.IsNotExist(err) {
// the error is caused by a missing directory, create it and retry // the error is caused by a missing directory, create it and retry
mkdirErr := os.MkdirAll(filepath.Dir(path), h.opt.DirMode) mkdirErr := os.MkdirAll(filepath.Dir(path), h.opt.dirMode)
if mkdirErr != nil { if mkdirErr != nil {
log.Print(mkdirErr) log.Print(mkdirErr)
} else { } else {
// try again // try again
tf, err = tempFile(tmpFn, h.opt.FileMode) tf, err = tempFile(tmpFn, h.opt.fileMode)
} }
} }
if err != nil { if err != nil {
@@ -759,13 +775,13 @@ func (h *Handler) createRepo(w http.ResponseWriter, r *http.Request) {
log.Printf("Creating repository directories in %s\n", h.path) log.Printf("Creating repository directories in %s\n", h.path)
if err := os.MkdirAll(h.path, h.opt.DirMode); err != nil { if err := os.MkdirAll(h.path, h.opt.dirMode); err != nil {
h.internalServerError(w, err) h.internalServerError(w, err)
return return
} }
for _, d := range ObjectTypes { for _, d := range ObjectTypes {
if err := os.Mkdir(filepath.Join(h.path, d), h.opt.DirMode); err != nil && !os.IsExist(err) { if err := os.Mkdir(filepath.Join(h.path, d), h.opt.dirMode); err != nil && !os.IsExist(err) {
h.internalServerError(w, err) h.internalServerError(w, err)
return return
} }
@@ -773,7 +789,7 @@ func (h *Handler) createRepo(w http.ResponseWriter, r *http.Request) {
for i := 0; i < 256; i++ { for i := 0; i < 256; i++ {
dirPath := filepath.Join(h.path, "data", fmt.Sprintf("%02x", i)) dirPath := filepath.Join(h.path, "data", fmt.Sprintf("%02x", i))
if err := os.Mkdir(dirPath, h.opt.DirMode); err != nil && !os.IsExist(err) { if err := os.Mkdir(dirPath, h.opt.dirMode); err != nil && !os.IsExist(err) {
h.internalServerError(w, err) h.internalServerError(w, err)
return return
} }