Dev (Back & Front)ARTIGO

sftpdav: Acesso Remoto via SSH com WebDAV

Foi assim que surgiu a ideia de criar o sftpdav, um programa que combina… remoto via SSH e montá-lo localmente como se fosse um compartilhamento WebDAV.

sftpdav: Acesso Remoto via SSH com WebDAV
Imagem: Cesar Gimenes

Recentemente, enfrentei um desafio ao tentar acessar arquivos de uma máquina que só permite conexão via SSH. Abrir portas adicionais ou instalar extensões de terceiros não eram opções viáveis por questões de segurança e compatibilidade, especialmente no macOS.

Foi assim que surgiu a ideia de criar o sftpdav, um programa que combina um cliente SFTP com um servidor WebDAV, permitindo acessar um diretório remoto via SSH e montá-lo localmente como se fosse um compartilhamento WebDAV.

Na prática, estou usando o rsync e mantendo os arquivos sincronizados entre a máquina local e o servidor remoto. O sftpdav é uma solução interessante, mas o desempenho não é tão bom. Ainda assim, foi muito proveitoso desenvolver essa solução e aprender mais sobre o protocolo WebDAV e SSH.

O código-fonte do sftpdav está disponível no GitHub: sftpdav.

Requisitos

A necessidade surgiu porque:

  • Ambiente Restrito: O servidor só permite conexão via SSH.
  • Segurança: Não posso expor outras portas no servidor.
  • Compatibilidade: O sshfs não tem suporte nativo no macOS, e não desejo instalar softwares adicionais.
  • Lock de Arquivos: O servidor WebDAV deve suportar bloqueio de arquivos (lock), necessário para meu caso de uso (o NFS também possui, mas não é tão simples de configurar).
  • user-space: A solução deve ser executada em user-space, sem necessidade de privilégios de administrador.

Com o sftpdav, é possível aproveitar a robustez do SSH e, ao mesmo tempo, oferecer a flexibilidade do WebDAV, que pode ser montado em sistemas Linux e macOS com comandos simples e em user-space.

Como Funciona o sftpdav

O programa realiza os seguintes passos:

  1. Leitura da Configuração SSH: Utiliza o arquivo ~/.ssh/config para obter informações como usuário, hostname, porta e arquivo de identidade.
  2. Conexão SFTP: Estabelece uma conexão SSH e, a partir dela, cria um cliente SFTP para acesso ao diretório remoto.
  3. Servidor WebDAV Local: Inicializa um servidor WebDAV com a biblioteca padrão do Go, expondo o diretório remoto via SFTP para ser montado localmente.
  4. Montagem do Compartilhamento: Com o servidor WebDAV em execução, o compartilhamento pode ser montado usando os comandos nativos do sistema.

Exemplos Práticos

Executando o sftpdav

Para iniciar o servidor WebDAV com acesso SFTP, execute:

bash
./sftpdav -port 8811 -host sshserver

Parâmetros suportados:

  • -host: Nome do host conforme configurado no ~/.ssh/config.
  • -port: Porta local para o servidor WebDAV (padrão: 8811).
  • -remoteDir: Diretório remoto a ser exposto (padrão: ".").

Montando o Compartilhamento

No Linux

Use o comando mount com o tipo davfs:

bash
sudo mount -t davfs http://localhost:8811 /mnt/sftp

No macOS

Use o comando mount_webdav:

bash
sudo mount_webdav http://localhost:8811 /mnt/sftp

Para Desmontar

Em ambos os sistemas, para desmontar o compartilhamento, execute:

bash
sudo umount /mnt/sftp

Limpando Arquivos de Dados Estendidos (macOS)

Como o WebDAV não suporta dados estendidos no macOS, podem ser criados arquivos iniciados por ._. Para removê-los, use:

bash
dot_clean /caminho/do/diretorio

A Versão Original

A versão original era mais simples, consistindo em poucas linhas de código para criar um servidor WebDAV. No entanto, ela precisava ser executada no servidor remoto:

package main

import (
    "flag"
    "log"
    "net/http"
    "time"

    "golang.org/x/net/webdav"
)

func main() {
    localPortFlag := flag.String("port", "8811", "Local port for WebDAV server")
    dirFlag := flag.String("dir", "./", "Directory to share")
    flag.Parse()

    handler := &webdav.Handler{
        Prefix:     "/",
        FileSystem: webdav.Dir(*dirFlag),
        LockSystem: webdav.NewMemLS(),
    }

    s := &http.Server{
        Handler:        handler,
        Addr:           ":" + *localPortFlag,
        ReadTimeout:    15 * time.Second,
        WriteTimeout:   15 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }

    if err := s.ListenAndServe(); err != nil {
        log.Fatal(err)
    }
}

Então, criava-se um túnel SSH para acessar o servidor remoto e montar o compartilhamento WebDAV localmente.

Criando um Túnel SSH

bash
ssh -L 8811:localhost:8811 sshserver

Neste exemplo, a porta 8811 da máquina local é redirecionada para a porta 8811 do servidor remoto, permitindo acesso local ao serviço WebDAV. Essa abordagem simples funcionava bem e é mais rápida que a versão atual.

Considerações Finais

sftpdav é uma solução experimental, mas funcional. Apesar de apresentar alguma lentidão, cumpre o objetivo de fornecer acesso remoto via WebDAV usando apenas a porta SSH, mantendo a segurança e a simplicidade do ambiente.

A experiência com este projeto reforçou como é possível combinar diferentes protocolos para superar limitações e criar soluções interessantes e seguras.

Caso tenha dúvidas ou sugestões, fique à vontade para entrar em contato ou abrir uma issue.

Cesar Gimenes

 

Cesar GimenesAutor

Trabalha com tecnologia desde a década de 90. Já atuou na área de educação e participou de projetos de mobilidade de grande volume para laboratórios farmacêuticos. Criou games tanto para PC, como para iOS. Hoje está direcionando seus esforços em plataformas de Sistemas Embarcados, IoT, microservices e cloud computing. É um entusiasta de tecnologias como Golang e Docker.

Ver perfil