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

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

Notes

Ins0mniA


Revision #2
Created 2025-09-04 03:51:52 EEST by Green
Updated 2025-09-10 19:45:19 EEST by Green