Skip to main content

Install a full samba share on Debian.

A ready-to-run Bash script for Debian 12 that installs Samba, configures a standalone file server with one public (guest) and one private (authenticated) share, enables the required services, validates the config, and opens the UFW firewall rule if UFW is active. This follows Debian’s simple server guidance, includes sample smb.conf best practices, and uses testparm to verify the configuration before starting services.

What it does

  • Installs Samba packages and utilities (samba, samba-common-bin, smbclient) needed for a file server on Debian 12 and checks smbd status to confirm installation.
  • Enables and starts the smbd and nmbd services for SMB file sharing and NetBIOS name service on a standalone server, consistent with Debian’s simple server flow.
  • Backs up the default smb.conf, writes a hardened standalone configuration (workgroup, server role, disable printing, guest mapping, usershare), and sets a minimum SMB protocol of SMB2 as documented in smb.conf references.
  • Creates a public share at /srv/samba/public (guest read/write) and a private share at /srv/samba/private (group-restricted), with POSIX permissions, SGID for group inheritance, and ACL-friendly VFS options.
  • Ensures the sambashare group exists, adds an optional UNIX user to that group, and registers the account in Samba’s database via smbpasswd -a for authenticated access.
  • Validates the configuration with testparm and restarts services to apply changes, following common Samba setup checks.
  • If UFW is installed and active, opens the “Samba” application profile (ports 137–139, 445), matching typical Debian/Ubuntu firewall examples for Samba.
Script
#!/usr/bin/env bash
# Full Samba file server setup for Debian 12 (Bookworm)
# - Creates public (guest) and private (authenticated) shares
# - Idempotent where possible
# - Run as root

set -euo pipefail

# Configurable defaults (override via environment)
WORKGROUP="${WORKGROUP:-WORKGROUP}"
SAMBA_GROUP="${SAMBA_GROUP:-sambashare}"
PUBLIC_DIR="${PUBLIC_DIR:-/srv/samba/public}"
PRIVATE_DIR="${PRIVATE_DIR:-/srv/samba/private}"
BACKUP_SUFFIX="$(date +%Y%m%d-%H%M%S)"

require_root() {
  if [ "${EUID:-$(id -u)}" -ne 0 ]; then
    echo "This script must be run as root."
    exit 1
  fi
}

install_packages() {
  export DEBIAN_FRONTEND=noninteractive
  apt-get update -y
  apt-get install -y samba samba-common-bin smbclient
}

enable_services() {
  systemctl enable --now smbd
  # nmbd provides NetBIOS name service/browsing; useful on many networks
  systemctl enable --now nmbd || true
  # winbind is optional for name resolution; enable but ignore errors if absent
  systemctl enable --now winbind || true
}

prepare_directories() {
  mkdir -p "$PUBLIC_DIR" "$PRIVATE_DIR"
  # Ensure group exists
  if ! getent group "$SAMBA_GROUP" >/dev/null; then
    groupadd -f "$SAMBA_GROUP"
  fi

  # Public: group-writable, guest access, inherit group via SGID
  chown root:"$SAMBA_GROUP" "$PUBLIC_DIR"
  chmod 2775 "$PUBLIC_DIR"

  # Private: group-restricted, authenticated users only, inherit group via SGID
  chown root:"$SAMBA_GROUP" "$PRIVATE_DIR"
  chmod 2770 "$PRIVATE_DIR"
}

write_smb_conf() {
  local conf="/etc/samba/smb.conf"
  if [ -f "$conf" ]; then
    cp -a "$conf" "${conf}.bak.${BACKUP_SUFFIX}"
  fi

  cat > "$conf" <<'EOF'
# Managed by setup script
# Reference: smb.conf(5)
[global]
   workgroup = WORKGROUP
   server role = standalone server
   netbios name = __NETBIOS_NAME__
   server string = Samba Server on %h
   map to guest = Bad User
   log file = /var/log/samba/log.%m
   max log size = 1000
   dns proxy = no

   # Usershares (optional; enables desktop-created shares if needed)
   usershare allow guests = yes

   # Disable printing support on a fileserver
   load printers = no
   printing = bsd
   printcap name = /dev/null
   disable spoolss = yes

   # Security hardening
   server min protocol = SMB2

   # Windows ACL compatibility on POSIX filesystems
   vfs objects = acl_xattr
   map acl inherit = yes
   store dos attributes = yes

[public]
   comment = Public Share (guest RW)
   path = __PUBLIC_PATH__
   browseable = yes
   read only = no
   guest ok = yes
   guest only = yes
   force user = nobody
   force group = __SAMBA_GROUP__
   create mask = 0664
   directory mask = 2775

[private]
   comment = Private Share (authenticated)
   path = __PRIVATE_PATH__
   browseable = yes
   read only = no
   valid users = @__SAMBA_GROUP__
   force group = __SAMBA_GROUP__
   create mask = 0660
   directory mask = 2770
   inherit permissions = yes
EOF

  # Substitute variables
  sed -i "s|WORKGROUP|${WORKGROUP}|g" "$conf"
  sed -i "s|__NETBIOS_NAME__|$(hostname -s)|g" "$conf"
  sed -i "s|__PUBLIC_PATH__|${PUBLIC_DIR}|g" "$conf"
  sed -i "s|__PRIVATE_PATH__|${PRIVATE_DIR}|g" "$conf"
  sed -i "s|__SAMBA_GROUP__|${SAMBA_GROUP}|g" "$conf"
}

add_optional_user() {
  echo
  read -r -p "Enter a UNIX username to grant private share access (leave blank to skip): " SAMBA_USER || true
  if [ -n "${SAMBA_USER:-}" ]; then
    if ! id "$SAMBA_USER" >/dev/null 2>&1; then
      # Create a local UNIX account without setting a system password
      adduser --disabled-password --gecos "" "$SAMBA_USER"
    fi
    usermod -aG "$SAMBA_GROUP" "$SAMBA_USER"
    echo "Set a Samba password for ${SAMBA_USER}:"
    smbpasswd -a "$SAMBA_USER"
  fi
}

check_and_restart() {
  echo "Validating Samba configuration with testparm..."
  testparm -s >/dev/null
  systemctl restart smbd
  systemctl restart nmbd || true
  systemctl restart winbind || true
}

maybe_open_firewall() {
  if command -v ufw >/dev/null 2>&1; then
    if ufw status | grep -qi "Status: active"; then
      ufw allow Samba || true
    fi
  fi
}

show_summary() {
  cat <<SUMMARY

Samba is installed and configured.

Shares:
  - \\\\$(hostname -s)\\public  (guest RW)
  - \\\\$(hostname -s)\\private (authenticated; users in group '${SAMBA_GROUP}')

Private-share access:
  - Add users with: usermod -aG ${SAMBA_GROUP} <user> && smbpasswd -a <user>

Validate:
  - testparm -s
  - systemctl status smbd

SUMMARY
}

main() {
  require_root
  install_packages
  enable_services
  prepare_directories
  write_smb_conf
  add_optional_user
  check_and_restart
  maybe_open_firewall
  show_summary
}

main "$@"
How to use
  • Save the script as samba-setup.sh, mark it executable with chmod +x samba-setup.sh, and run it as root on a fresh Debian 12 system.
  • During the run, optionally specify a UNIX account to grant private share access; the script adds it to the Samba group and registers it with smbpasswd -a for authentication.
  • Access from Linux with smbclient, for example: smbclient //HOSTNAME/private -U USER, or test locally per Debian’s simple server guidance using smbclient commands.

Notes

  • The services to manage on a standalone server are smbd (and optionally nmbd/winbind), and systemctl status smbd confirms the server daemon status on Debian 12.
  • The configuration file is /etc/samba/smb.conf; test changes with testparm and consult the smb.conf(5) reference for parameters like workgroup, server role, and server min protocol.
  • If UFW is enabled, the script opens the Samba profile; alternatively, iptables/nftables rules covering UDP 137–138 and TCP 139/445 can be used as demonstrated in Debian’s simple server page.