1
0
Fork 0
mirror of https://github.com/restic/restic.git synced 2025-03-09 00:00:02 +01:00

Update latest fixes from rclone SMB

Update documentation. Use cloudsoda fork of smb library for fixes related to size calculations and allowing to use hostnames.
This commit is contained in:
aneesh-n 2024-09-02 16:38:24 -06:00
parent 56afe8d9b1
commit b041701b74
No known key found for this signature in database
GPG key ID: 6F5A52831C046F44
6 changed files with 41 additions and 21 deletions

View file

@ -629,18 +629,21 @@ The region, where a bucket should be created, can be specified with the ``-o gs.
SMB/CIFS
********
In order to backup data to SMB/CIFS, you must specify the host (with port if not default port `445`) as the backend.
You must first setup the following environment variables with the SMB credentials and the domain if it is not the default `WORKGROUP`.
To backup data to SMB/CIFS, specify the host (with port if not default port `445`) as the backend.
You can set the following environment variables with the SMB credentials:
.. code-block:: console
$ export RESTIC_SMB_USER=<MY_SMB_USER>
$ export RESTIC_SMB_PASSWORD=<MY_SMB_PASSWORD>
$ export RESTIC_SMB_DOMAIN=<MY_SMB_DOMAIN>
$ export RESTIC_SMB_SPN=<MY_SMB_SPN>
The domain defaults to `WORKGROUP` if not specified.
The SPN (Service Principal Name) is optional and can be used for further authentication
with some servers, particularly clusters, for example ``cifs/remotehost:1020``.
Once the server is configured, the setup of the SMB repository can
simply be achieved by changing the URL scheme in the ``init`` command:
To set up an SMB repository, use the `smb://` URL scheme in the `init` command:
.. code-block:: console
@ -651,8 +654,22 @@ simply be achieved by changing the URL scheme in the ``init`` command:
Please note that knowledge of your password is required to access the repository.
Losing your password means that your data is irrecoverably lost.
Optionally, you can also pass the ``user``, ``password`` and ``domain`` as options. Configurations specified as options take highest precendence.
You can also specify other smb specific optional configurations like ``dialect``, ``client-guid``, ``require-message-signing``, ``idle-timeout`` and ``connections`` as options.
Optionally, you can also pass `user`, `password`, `domain`, and `spn` as options.
Options take precedence over environment variables.
Additional SMB-specific options include:
- `connections`: Set the number of concurrent operations (default: 5)
- `idle-timeout`: Max time in seconds before closing idle connections (default: 60)
- `require-message-signing`: Mandate message signing (default: false)
- `dialect`: Force a specific SMB dialect (default: 0, which tries dialects in order)
- `client-guid`: A 16-byte GUID to uniquely identify a client (default: random GUID)
Example with options:
.. code-block:: console
$ restic -r smb://host:445/sharename/restic-repo -o smb.user=myuser -o smb.password=mypass -o smb.connections=10 -o smb.idle-timeout=120s init
Other Services via rclone
*************************

2
go.mod
View file

@ -9,12 +9,12 @@ require (
github.com/anacrolix/fuse v0.3.1
github.com/cenkalti/backoff/v4 v4.3.0
github.com/cespare/xxhash/v2 v2.3.0
github.com/cloudsoda/go-smb2 v0.0.0-20231124195312-f3ec8ae2c891
github.com/elithrar/simple-scrypt v1.3.0
github.com/go-ole/go-ole v1.3.0
github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.6.0
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/hirochachacha/go-smb2 v1.1.0
github.com/klauspost/compress v1.17.9
github.com/minio/minio-go/v7 v7.0.74
github.com/ncw/swift/v2 v2.0.2

5
go.sum
View file

@ -47,6 +47,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudsoda/go-smb2 v0.0.0-20231124195312-f3ec8ae2c891 h1:nPP4suUiNage0vvyEBgfAnhTPwwXhNqtHmSuiCIQwKU=
github.com/cloudsoda/go-smb2 v0.0.0-20231124195312-f3ec8ae2c891/go.mod h1:xFxVVe3plxwhM+6BgTTPByEgG8hggo8+gtRUkbc5W8Q=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@ -125,8 +127,6 @@ github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDP
github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hirochachacha/go-smb2 v1.1.0 h1:b6hs9qKIql9eVXAiN0M2wSFY5xnhbHAQoCwRKbaRTZI=
github.com/hirochachacha/go-smb2 v1.1.0/go.mod h1:8F1A4d5EZzrGu5R7PU163UcMRDJQl4FtcxjBfsY8TZE=
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
@ -225,7 +225,6 @@ go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnw
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=

View file

@ -29,8 +29,8 @@ type Config struct {
User string `option:"user" help:"specify the SMB user for NTLM authentication."`
Password options.SecretString `option:"password" help:"specify the SMB password for NTLM authentication."`
Domain string `option:"domain" help:"specify the domain for authentication."`
SPN string `option:"spn" help:"specify the service principal name for authentication. This name is presented to the server. Some servers use this as further authentication, and it often needs to be set for clusters. For example: cifs/remotehost:1020. Leave blank if not sure."`
Layout string `option:"layout" help:"use this backend directory layout (default: auto-detect)"`
Connections uint `option:"connections" help:"set a limit for the number of concurrent operations (default: 5)"`
IdleTimeout time.Duration `option:"idle-timeout" help:"Max time in seconds before closing idle connections. If no connections have been returned to the connection pool in the time given, the connection pool will be emptied. Set to 0 to keep connections indefinitely.(default: 60)"`
RequireMessageSigning bool `option:"require-message-signing" help:"Mandates message signing otherwise does not allow the connection. If this is false, messaging signing is just enabled and not enforced. (default: false)"`
@ -117,5 +117,8 @@ func (cfg *Config) ApplyEnvironment(prefix string) error {
cfg.Domain = DefaultDomain
}
}
if cfg.SPN == "" {
cfg.SPN = os.Getenv(prefix + "RESTIC_SMB_SPN")
}
return nil
}

View file

@ -6,9 +6,8 @@ import (
"fmt"
"net"
"strconv"
"sync/atomic"
"github.com/hirochachacha/go-smb2"
"github.com/cloudsoda/go-smb2"
"github.com/restic/restic/internal/debug"
)
@ -67,17 +66,17 @@ func (c *conn) isClosed() bool {
// addSession increments the active session count when an SMB session needs to be used.
// If this is called, we must call removeSession when we are done using the session.
func (b *SMB) addSession() {
atomic.AddInt32(&b.sessions, 1)
b.sessions.Add(1)
}
// removeSession decrements the active session count when it is no longer in use.
func (b *SMB) removeSession() {
atomic.AddInt32(&b.sessions, -1)
b.sessions.Add(-1)
}
// getSessionCount returns the number of active sessions.
func (b *SMB) getSessionCount() int32 {
return atomic.LoadInt32(&b.sessions)
return b.sessions.Load()
}
// dial starts a client connection to the given SMB server. It is a
@ -99,13 +98,14 @@ func (b *SMB) dial(ctx context.Context, network, addr string) (*conn, error) {
ClientGuid: clientID,
},
Initiator: &smb2.NTLMInitiator{
User: b.User,
Password: b.Password.Unwrap(),
Domain: b.Domain,
User: b.User,
Password: b.Password.Unwrap(),
Domain: b.Domain,
TargetSPN: b.SPN,
},
}
session, err := d.DialContext(ctx, netConn)
session, err := d.DialConn(ctx, netConn, addr)
if err != nil {
return nil, fmt.Errorf("SMB session initialization failed: %w", err)
}

View file

@ -10,6 +10,7 @@ import (
"path"
"path/filepath"
"sync"
"sync/atomic"
"time"
"github.com/restic/restic/internal/backend"
@ -44,7 +45,7 @@ import (
// SMB is a backend which stores the data on an SMB share.
type SMB struct {
sessions int32
sessions atomic.Int32
poolMu sync.Mutex
pool []*conn
drain *time.Timer // used to drain the pool when we stop using the connections