A Unix daemon that makes your Linux/macOS/BSD machine visible in Network view of Windows Explorer on newer versions of Windows.
It implements WS-Discovery protocol that Windows now uses to discover machines on local network. It is a native daemon, written in C++.
- Fully supports macOS, Linux and FreeBSD
- Can be configured via a configuration file, not just command line.
- Discovers Samba/macOS SMB configuration on its own. (This can be overridden, if desired)
- Integrates well with
systemd
andlaunchd
. Of course it can also run as a classical Unix daemon for other init systems. - Friendly to various log rotation methods like
newsyslogd
andlogrotate
. Supports standard reload semantics via SIGHUP. - Written with security in mind first and foremost.
- Will never run any network code as root. Designated user account to run under is created automatically, if needed.
There are a couple of similar projects available: wsdd written in Python and wsdd2 written in C. Neither of them, however, fully provides the features above.
The biggest drawback of wsdd-native compared to these projects is that it requires modern (as of 2022) C++ compiler to build and set of modern libc
, libstdc++
/libc++
etc. to run. This usually limits it to recent versions of operating systems it supports. (It is possible to build it on older ones with newer toolchains but doing so is non-trivial). Of course, as time passes this limitation will become less and less significant.
Pre-built packages are available in a custom apt repository for systems newer than Ubuntu 20.04 (focal) or Debian 11 (bullseye). Any Debian system based upon those or newer should work.
Both amd64
(aka x86_64
) and arm64
(aka aarch64
) architectures are supported.
To set up the apt repository:
-
Add new repo
echo "deb" \ "[arch=$(dpkg --print-architecture)]" \ "https://www.gershnik.com/apt-repo/" \ "base" \ "main" \ | sudo tee /etc/apt/sources.list.d/wsddn.list >/dev/null
-
Import the repository public key
wget -qO- https://www.gershnik.com/apt-repo/conf/pgp-key.public \ | sudo tee /etc/apt/trusted.gpg.d/gershnik.asc >/dev/null
Once the repository is set up you can install wsddn
as usual via:
sudo apt update
sudo apt install wsddn
Daemon will be enabled and started automatically on first install but keep its existing state on updates. To start/stop/reload it use
sudo systemctl start wsddn
sudo systemctl stop wsddn
sudo systemctl reload wsddn
Configuration file will be at /etc/wsddn.conf
. Comments inside indicate available options and their meaning.
You can also use man wsddn
to learn about configuration or see online version here
Daemon log can be viewed via journalctl
as usual
journalctl -u wsddn
Pre-built packages are available in a custom rpm repository. It provides "el9" packages that should work for RHEL9/CentOS Stream 9/Fedora 34 or above.
Both amd64
(aka x86_64
) and arm64
(aka aarch64
) architectures are supported.
To set the repo up:
sudo dnf config-manager --add-repo https://www.gershnik.com/rpm-repo/gershnik.repo
Once the repository is set up you can install wsddn
as usual via
sudo dnf install wsddn
On first install firewall ports 5357/tcp
and 3702/udp
will be opened.
On RHEL/Centos daemon will be enabled and started automatically on first install but keep its existing state on updates.
On Fedora you need to manually enable and start the daemon:
sudo systemctl enable wsddn
sudo systemctl start wsddn
To start/stop/reload it use
sudo systemctl start wsddn
sudo systemctl stop wsddn
sudo systemctl reload wsddn
Configuration file will be at /etc/wsddn.conf
. Comments inside indicate available options and their meaning.
You can also use man wsddn
to learn about configuration or see online version here
Daemon log can be viewed via journalctl
as usual
journalctl -u wsddn
Pre-built packages are available for FreeBSD 13 in a custom binary package repository.
Both amd64
(aka x86_64
) and arm64
(aka aarch64
) architectures are supported.
To set the repo up:
- Create the custom repo config folder if it does not already exist
sudo mkdir -p /usr/local/etc/pkg/repos
- Download the repository public key
wget -qO- https://www.gershnik.com/bsd-repo/rsa-key.pub \ | sudo tee /usr/local/etc/pkg/repos/www_gershnik_com.pub > /dev/null
- Create a file named
/usr/local/etc/pkg/repos/www_gershnik_com.conf
- Put the following content in it:
www_gershnik_com: { url: "https://www.gershnik.com/bsd-repo/${ABI}", signature_type: "pubkey", pubkey: "/usr/local/etc/pkg/repos/www_gershnik_com.pub", enabled: yes }
Once the repository is set up you can install wsddn
as usual via
sudo pkg update
sudo pkg install wsddn
As is standard on FreeBSD daemon will not be enabled or started after installation. To enable it, edit /etc/rc.conf
and add
the following line there:
wsddn_enable="YES"
To start/stop/reload the daemon use:
sudo service wsddn start
sudo service wsddn stop
sudo service wsddn reload
Configuration file will be at /usr/local/etc/wsddn.conf
. Comments inside indicate available options and their meaning.
You can also use man wsddn
to learn about configuration or see online version here
Log file is located at /var/log/wsddn.log
. Log file rotation is configured via newsylogd
. To modify rotation settings edit /usr/local/etc/newsyslog.conf.d/wsddn.conf
On macOS there are 2 ways to install wsddn
: via a standalone installer package or Macports.
Using a standalone installer is simpler but you will have to manually install any future updates as well.
Macports is a bit more complicated to set up and requires Xcode to be present but it provides updatability
similar to Linux package managers.
Note that currently there is no support for Homebrew.
Installer package is available for macOS Catalina (10.15) and above on both Intel and Apple Silicon.
To install wsddn
- Navigate to Releases page.
- Expand the release you wish to install and download
wsddn-macos-x.x.pkg
- Launch it to run GUI installer or, if you prefer, install on command line via
sudo installer -pkg /path/to/wsddn-macos-x.x.pkg -target /
To fully uninstall wsddn
run /usr/local/bin/wsddn-uninstall
Daemon will start automatically on install.
To start/stop/reload the daemon use:
sudo launchctl kickstart system/io.github.gershnik.wsddn
sudo launchctl kill TERM system/io.github.gershnik.wsddn
sudo launchctl kill HUP system/io.github.gershnik.wsddn
Configuration file will be at /etc/wsddn.conf
. Comments inside indicate available options and their meaning.
You can also use man wsddn
to learn about configuration or see online version here
Daemon and related logs can be viewed in system log by searching for subsystem or
process names containing string wsddn
. For example:
log show --last 15m --debug --info \
--predicate 'subsystem CONTAINS "wsddn" OR process CONTAINS "wsddn"'
Macports package is provided that can be installed on both Intel and Apple Silicon Macs. macOS versions supported are macOS Catalina (10.15) and above.
To set the repo up:
sudo bash <<'___'
set -e
pemurl=https://gershnik.com/macports-repo/macports.pem
porturl=https://www.gershnik.com/macports-repo/ports.tar.bz2
prefix=$(dirname $(dirname $(which port)))
pemfile="$prefix/share/macports/gershnik.pem"
pubkeysfile="$prefix/etc/macports/pubkeys.conf"
sourcesfile="$prefix/etc/macports/sources.conf"
curl -s $pemurl > "$pemfile"
grep -qxF "$pemfile" "$pubkeysfile" || echo $pemfile >> "$pubkeysfile"
grep -qxF "$porturl" "$sourcesfile" || echo $porturl >> "$sourcesfile"
sudo port sync
___
Then you can install wsddn
as usual via
sudo port install wsddn
Daemon will start automatically on install.
To start/stop/reload the daemon use:
sudo launchctl kickstart system/org.macports.wsddn
sudo launchctl kill TERM system/org.macports.wsddn
sudo launchctl kill HUP system/org.macports.wsddn
Configuration file will be at /opt/local/etc/wsddn.conf
. Comments inside indicate available options and their meaning.
You can also use man wsddn
to learn about configuration or see online version here
Daemon and related logs can be viewed in system log by searching for subsystem or
process names containing string wsddn
. For example:
log show --last 15m --debug --info \
--predicate 'subsystem CONTAINS "wsddn" OR process CONTAINS "wsddn"'
- Git
- C++20 capable compiler. Compilers known to work are GCC 11.3, Clang 13, Xcode 13 or above.
- CMake 3.23 or greater. If your distribution CMake is older than that you can download a newer version from https://cmake.org/download/
- Optional: if you wish to enable
systemd
integration make sure you havelibsystemd
library and headers installed on your system. On APT systems use:On DNF systems usesudo apt install libsystemd-dev
sudo dnf install systemd-devel
git clone https://github.com/gershnik/wsdd-native.git
cd wsdd-native
mkdir -p out
cd out
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DFETCHCONTENT_QUIET=OFF ..
cmake --build .
sudo cmake --install . --strip
The wsddn
executable will be installed into /usr/local/bin
and manpage added to section 8 of the manual.
The following flags can be passed to CMake configure step:
-DWSDDN_PREFER_SYSTEM=ON|OFF
This controls whether to prefer system version of 3rd party libraries or fetch, build and use static ones. Currently only libxml2
is affected.
On Linux:
-DWSDDN_WITH_SYSTEMD="yes"|"no"|"auto"
.
This controls whether to enable systemd
integration. Auto performs auto-detection (this is the default).
The config directory of this repo contains sample configuration files for different init systems (systemd, FreeBSD rc.d and macOS launchd). You can adapt those as appropriate to your system.
Command line flags and configuration file entries are documented in man wsddn
and online here
Note: The following instructions are copied verbatim from wsdd one since the requirements are identical
Traffic for the following ports, directions and addresses must be allowed.
- incoming and outgoing traffic to
udp/3702
with multicast destination:239.255.255.250
for IPv4ff02::c
for IPv6
- outgoing unicast traffic from
udp/3702
- incoming to
tcp/5357
You should further restrict the traffic to the (link-)local subnet, e.g. by using the fe80::/10
address space for IPv6. Please note that IGMP traffic must be enabled in order to get IPv4 multicast traffic working.
There are two main security concerns with a daemon that delivers data about local machine over the network
- A bug inside daemon code may allow remote attacker to penetrate the machine running it.
- The information legitimately provided by the daemon will disclose something to an attacker that would otherwise remain unknown, enabling him to mount further attacks.
Currently the implementation ignores the second concern. The things wsdd-native discloses are the existence of the local host, its name, presence of Samba on it and domain/workgroup membership. All of these are generally disclosed by Samba itself via SMB broadcasts so, assuming the firewall is configured as described above, there is no net gain for an attacker. WS-Discovery protocol contains provisions for encrypting its HTTP traffic and potentially authenticating clients accessing your host via their client certificates. This limits exposure somewhat but at a significant configuration and maintenance cost. If there is interest in any of it it is possible to easily add this functionality in a future version.
The first concern is by far the most significant one. All software contains bugs and despite developer's best efforts there is always a risk that a bad actor can discover some kind of input that allows him to hijack the server process. To address this possibility wsdd-native takes the following measures (apart from general secure coding practices):
- The process performing network communications never runs as root. If launched as root it will create an unprivileged account (
_wsddn:_wsddn
on macOS andwsddn:wsddn
on other platforms) and run network process under it. - Similarly when started as root the daemon will lock the network process in a chroot jail (
/var/empty
on macOS and/var/run/wsddn
on other platforms).
These measures are automatic and cannot be bypassed. Taken together they should limit the fallout of any vulnerability though, of course, nothing ever can be claimed to be 100% secure.
Note that when running on systemd
systems it is recommended to use its DynamicUser
facility instead of running as root and relying on the measures above. The Debian/Ubuntu installer does so.
wsdd-native is directly influenced by wsdd. While no source code from it was directly re-used in this project, many design and implementation ideas were; as well as command line design and some documentation content.
See Acknowledgements.md for information about open source libraries used in this project.
Please use the GitHub issue tracker to report any bugs or suggestions.