Post
Quando o Samba funciona, mas desaparece do Windows Explorer
Um share guest bloqueado pelo diretório-pai e um servidor invisível sem WS-Discovery pareciam uma falha única. Eram problemas diferentes, com testes diferentes.
Seis atalhos do Windows apontavam para compartilhamentos que pareciam ter desaparecido:
1
2
3
4
5
6
\\192.168.0.140\common-shared
\\192.168.0.140\inbox-empresa
\\192.168.0.140\inbox-geral
\\192.168.0.140\inbox-pessoal
\\192.168.0.140\public-shared
\\192.168.0.140\work-shared
As portas SMB respondiam, mas o Explorer não mostrava os diretórios. Depois que o acesso direto voltou, surgiu uma segunda estranheza: o servidor continuava ausente em Rede no Windows 11.
Os dois sintomas pareciam parte da mesma falha. O diagnóstico mostrou duas causas independentes:
- uma permissão Unix no diretório-pai bloqueava um dos acessos guest;
- o Samba não publicava o servidor pelo mecanismo usado pelo Explorer moderno.
A diferença importa porque cada camada exige um teste próprio. Uma porta 445 aberta não demonstra que o share aceita determinada identidade. Um share acessível por caminho UNC também não demonstra que o servidor será descoberto na tela Rede.
O que eu precisava distinguir
O servidor era um LXC com Debian 13 no Proxmox, disponível em
192.168.0.140. O Samba, gerenciado por Ansible, oferecia seis áreas:
| Share | Política |
|---|---|
inbox-geral |
privado, leitura e escrita por gpupo |
inbox-empresa |
privado, leitura e escrita por gpupo |
inbox-pessoal |
privado, leitura e escrita por gpupo |
work-shared |
escrita por gpupo e pelo grupo sambashare |
common-shared |
leitura guest e escrita autenticada |
public-shared |
leitura e escrita guest |
O cliente usado no diagnóstico foi o node6, um Windows 11 em
192.168.0.56.
Antes de mudar a configuração, separei três perguntas:
1
2
3
4
5
TCP 445 responde?
↓
o share aceita a identidade usada?
↓
o servidor é descoberto pelo Explorer?
Essa sequência acabou sendo mais útil que tratar “o Samba não funciona” como um único estado.
A porta respondia, mas o acesso guest falhava
Comecei pelo servidor, sem reiniciar serviços:
1
2
3
4
systemctl is-active smbd nmbd
testparm -s
ss -lntp | grep -E ':139|:445'
smbstatus --shares
O resultado enfraqueceu a hipótese de falha geral:
smbdenmbdestavam ativos;testparmcarregava a configuração sem erros;- os seis shares apareciam na configuração efetiva;
- existia uma conexão aberta em
common-shared.
O host tinha iniciado pouco antes, o que explicava parte da indisponibilidade
vista minutos antes. Não explicava, porém, por que o acesso guest ao
common-shared ainda recebia STATUS_ACCESS_DENIED.
Testei os seis caminhos pelo protocolo SMB com a credencial mantida fora do repositório. Todos funcionaram de forma autenticada. Como guest, o resultado foi diferente:
1
2
3
public-shared: OK
common-shared: STATUS_ACCESS_DENIED
inbox-geral: STATUS_ACCESS_DENIED (esperado)
Se public-shared aceitava guest, uma explicação genérica como “o Windows
bloqueia acesso anônimo” não cobria o que eu observava. A diferença estava nos
caminhos ou na identidade efetiva usada por cada share.
A permissão problemática estava um nível acima
A configuração do common-shared parecia coerente com a política:
1
2
3
4
5
6
[common-shared]
path = /data/common-shared
browseable = yes
read only = yes
guest ok = yes
write list = gpupo
O próprio diretório também não indicava o bloqueio:
1
drwxr-xr-x gpupo:gpupo /data/common-shared
O detalhe apareceu quando inspecionei todos os componentes do caminho:
1
namei -l /data/common-shared
1
2
3
drwxr-xr-x root:root /
drwx------ gpupo:gpupo data
drwxr-xr-x gpupo:gpupo common-shared
O diretório /data estava em 0700. Quando o Samba mapeava um usuário
desconhecido para a conta guest nobody, essa conta não conseguia atravessar o
diretório-pai. O log registrava a mesma identidade e a mesma falha:
1
2
vfs_ChDir(/data/common-shared) failed: Permission denied
Current token: uid=65534, gid=65534
Esse comportamento corresponde à resolução de caminhos no Linux: cada
componente intermediário precisa conceder permissão de busca, representada pelo
bit de execução em diretórios. Sem ela, a resolução termina com EACCES, ainda
que o diretório final tenha permissões mais abertas. A distinção entre leitura
e busca está descrita em
path_resolution(7).
O public-shared escondia o problema porque sua configuração usava
force user = gpupo. A operação acabava executada com uma identidade que podia
atravessar /data. Os dois shares aceitavam guest no Samba, mas chegavam ao
sistema de arquivos com identidades diferentes.
0711 abriu a travessia, não a listagem
Minha correção foi alterar somente a raiz /data para 0711:
1
2
3
4
5
6
7
- name: Garantir raiz de dados atravessavel pelos acessos guest
ansible.builtin.file:
path: /data
state: directory
owner: gpupo
group: gpupo
mode: "0711"
O bit de execução permite atravessar o diretório quando o nome do próximo
componente é conhecido. Como a conta guest não recebeu leitura na raiz, ela
continua sem poder listar o conteúdo de /data.
As permissões específicas permaneceram nos diretórios finais:
1
2
3
4
5
6
7
/data 0711
/data/inbox-geral 0700
/data/inbox-empresa 0700
/data/inbox-pessoal 0700
/data/work-shared 2770
/data/common-shared 0755
/data/public-shared 0777
Isso não torna 0711 uma recomendação universal para toda raiz de shares. A
decisão fez sentido aqui porque os nomes publicados pelo Samba são conhecidos,
os diretórios privados continuam fechados e a política de cada share permanece
explícita. ACLs, identidades forçadas ou outra organização de caminhos podem
pedir uma fronteira diferente.
O playbook precisava provar mais que a configuração
Durante o diagnóstico encontrei uma falha no próprio processo de automação. O
playbook tentava usar smbclient, mas não instalava o pacote. A validação
também acontecia antes de a configuração ser publicada e antes de os serviços
estarem garantidos como ativos.
Reordenei o fluxo para:
- instalar
samba,samba-common,smbcliente, depois,wsdd2; - criar usuários, grupos e diretórios;
- validar o template antes de substituir
smb.conf; - garantir os serviços ativos;
- aplicar handlers pendentes;
- listar os seis shares com autenticação;
- listar
common-sharedepublic-sharedcomo guest.
O template passou a usar a validação oferecida pelo módulo
ansible.builtin.template:
1
2
3
4
5
6
7
8
9
- name: Deploy Samba smb.conf configuration
ansible.builtin.template:
src: "/../templates/services/samba.conf.j2"
dest: /etc/samba/smb.conf
owner: root
group: root
mode: "0644"
validate: testparm -s %s
notify: Restart Samba services
Depois da correção, uma segunda execução terminou assim:
1
samba-server: ok=15 changed=0 failed=0
Nesse ponto eu tinha evidência para a segunda pergunta: os shares aceitavam as identidades esperadas. Ainda não tinha respondido por que o servidor não aparecia em Rede.
Acesso por UNC e descoberta são capacidades diferentes
No node6, o caminho direto funcionava:
1
Test-Path '\\192.168.0.140\common-shared'
1
True
Mesmo assim, o servidor não aparecia em Explorador de Arquivos → Rede.
A documentação da Microsoft explica a separação histórica: o antigo serviço Computer Browser dependia de SMB1 e, sem ele, o Explorer deixa de listar computadores pelo método legado de browsing via datagramas NetBIOS. O Windows 11 não instala cliente nem servidor SMB1 por padrão, e a Microsoft recomenda não reinstalar o protocolo por causa de seus problemas de segurança.
A FAQ do
Samba
descreve a consequência prática: com SMB2 ou SMB3, o recurso ainda pode ser
aberto diretamente por nome ou IP, enquanto a descoberta de rede usa WSD e
LLMNR. Era exatamente a divisão observada no node6.
Minha configuração manteve min protocol = SMB2. Reativar SMB1 para recuperar
a tela Rede teria alterado o protocolo de compartilhamento para corrigir um
problema de publicação.
O servidor passou a responder por WS-Discovery
No Debian 13 usado no LXC, apt-cache não apresentava candidato para wsdd,
mas oferecia wsdd2 na versão 1.8.7+dfsg-1.2. O
wsdd2 empacotado pelo
Debian é descrito como um daemon WSD
que anuncia compartilhamentos e responde a Probes de clientes Windows. O pacote
também implementa resolução multicast por LLMNR.
Acrescentei o pacote e o serviço ao playbook do Samba:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- name: Install Samba packages
ansible.builtin.apt:
name:
- samba
- samba-common
- smbclient
- wsdd2
state: present
- name: Ensure Samba services are enabled and started
ansible.builtin.service:
name: ""
state: started
enabled: true
loop:
- smbd
- nmbd
- wsdd2
Depois do deploy, observei o daemon em UDP e TCP 3702, usados na descoberta e
na troca de metadados, e em UDP e TCP 5355 para LLMNR. O nome anunciado era
SAMBA-SERVER, no workgroup WORKGROUP.
O nmbd permaneceu ativo para compatibilidade e nomes NetBIOS. O resultado do
teste, porém, não dependia de reativar o browsing legado.
Eu também normalizei o lado do Windows
No cliente encontrei este estado:
1
2
3
Rede "Cogumelo": Public
fdPHost: Running / Manual
FDResPub: Stopped / Manual
Como se tratava de uma rede doméstica confiável, criei um playbook dedicado ao
node6 que:
- altera somente perfis de rede ativos para
Private; - mantém
fdPHosteFDResPubautomáticos e ativos; - habilita somente as regras privadas do grupo nativo Network Discovery;
- confirma que
common-sharedcontinua acessível.
Os serviços ficaram declarados assim:
1
2
3
4
5
6
7
8
- name: Garantir servicos de descoberta ativos
ansible.windows.win_service:
name: ""
start_mode: auto
state: started
loop:
- fdPHost
- FDResPub
As regras foram selecionadas por grupo e perfil, sem abrir portas para o perfil público:
1
2
3
4
5
6
Get-NetFirewallRule -DisplayGroup 'Network Discovery' |
Where-Object {
$_.Profile.ToString() -match 'Private' -and
$_.Enabled -ne 'True'
} |
Enable-NetFirewallRule
A orientação da Microsoft para diagnosticar aplicações WSD inclui verificar a exceção de firewall Network Discovery e as portas de descoberta e troca de metadados. Esse é o limite que usei para as regras, conforme a documentação de configuração de adaptador e firewall.
A segunda execução do playbook do Windows também ficou limpa:
1
node6: ok=4 changed=0 failed=0
Eu não isolei cada mudança do cliente em experimentos separados. Portanto, o resultado não demonstra que mudar o perfil, iniciar os dois serviços e habilitar as regras tenham sido individualmente necessários para este servidor aparecer. O que validei foi o estado final desejado e o tráfego WSD completo nesse estado.
A interface do Explorer não foi meu teste principal
Uma sessão SSH no Windows não reproduz perfeitamente o namespace, o cache e o ciclo de atualização da sessão gráfica do Explorer. Em vez de tratar a tela Rede como única evidência, validei as etapas do protocolo:
- o
node6enviou um Probe multicast para239.255.255.250:3702; - o
wsdd2recebeu o Probe; - o
node6recebeuProbeMatchesde192.168.0.140; SAMBA-SERVERresolveu para192.168.0.140por LLMNR;- o cliente alcançou TCP 3702 para obter os metadados WSD;
\\SAMBA-SERVER\common-sharedabriu e listou o conteúdo.
O fluxo é compatível com a especificação publicada pela Microsoft: o cliente envia um Probe multicast e o serviço descoberto devolve um Probe Match. A sequência está descrita no cenário de descoberta dinâmica por WS-Discovery.
O resumo do teste ficou assim:
1
2
3
4
5
6
wsd-server=192.168.0.140
probe-match=True
resolved-address=192.168.0.140
tcp445=True
wsd-tcp3702=True
share-by-name=True
Esse teste prova mais que uma captura da interface: o servidor respondeu ao protocolo, o nome resolveu, as portas necessárias estavam alcançáveis e o share abriu pelo nome anunciado.
Dois falsos caminhos também fizeram parte do diagnóstico
Meu primeiro Probe manual foi rejeitado pelo wsdd2 como
Unsupported query. O XML era semanticamente equivalente ao esperado e outros
dispositivos responderam, mas eu tinha usado aliases de namespace como a: e
d:. O parser do wsdd2 esperava os prefixos convencionais wsa: e wsd:.
Quando repeti o envelope com esses prefixos, o Samba respondeu imediatamente
com ProbeMatches.
Não generalizo esse resultado para XML ou para toda implementação de WS-Discovery. Foi uma incompatibilidade observada neste parser, nesta versão, durante um teste manual.
Também investiguei a bridge e o firewall do Proxmox porque um listener auxiliar
parecia não receber multicast. O debug do próprio wsdd2 mostrou que o Probe do
node6 chegava normalmente. Descartei a hipótese de bloqueio na virtualização
sem alterar o firewall.
O estado que consigo sustentar
Ao final da manutenção:
- os seis shares funcionavam com autenticação;
common-sharedepublic-sharedfuncionavam como guest;SAMBA-SERVERrespondia a Probes WS-Discovery;- o
node6resolvia o nome e abria o share sem usar o IP; - o Windows estava em perfil privado, com os serviços e as regras de descoberta declarados pelo playbook;
- os dois playbooks repetiam com
changed=0; - a configuração operacional estava registrada na Wiki do homelab.
Neste ambiente, “Samba funcionando” precisava ser dividido em disponibilidade,
autorização e descoberta. Para uma ocorrência semelhante, eu começaria pelos
mesmos limites: testaria TCP 445, depois cada share com a identidade relevante
e somente então o Probe WSD. Essa ordem reduz a chance de alterar o firewall ou
reativar um protocolo legado para corrigir uma permissão que estava em
/data.
Ambiente validado em 18 de agosto de 2026: Debian 13 em LXC/Proxmox, Samba 4.22.10, wsdd2 1.8.7, Windows 11 e Ansible Core 2.21.1.