English | 中文
A high-performance NFS (Network File System) server for Windows, written in Rust. Supports NFSv3, NFSv4.1, and NFSv4.2, enabling Linux/Unix clients to mount Windows directories transparently.
- NFSv3 — Full protocol support (MOUNT, PORTMAP, NFSv3 procedures)
- NFSv4.1 — COMPOUND operations, SEQUENCE, OPEN, CLOSE, READ, WRITE, READDIR, LOCK/LOCKU, SETATTR, and more
- NFSv4.2 — READ_PLUS, COPY, SEEK, CLONE, plus 9 stub operations per RFC 7862
- Native Windows Service — Install/uninstall as a Windows Service with automatic startup
- Dual-stack NFS — Run NFSv3, NFSv4.1, and NFSv4.2 simultaneously on the same port (2049)
- MOUNT protocol — NFSv3 MOUNT protocol on port 20048
- PORTMAP — RPC portmapper on port 111 (TCP + UDP)
- Async I/O — Built on Tokio for high concurrency
- Flexible configuration — TOML-based config with per-export access control (CIDR)
- TLS encryption — Built-in TLS support (rustls) for encrypted NFS transport (SEC-015)
- Structured logging — Rolling log files with configurable level and rotation
RustNfsSvc/
├── src/
│ ├── main.rs # Entry point: CLI arg parsing (install/uninstall/service/standalone)
│ ├── path_ext.rs # Windows \\?\ extended-path helper (MAX_PATH fix)
│ ├── service.rs # Windows Service lifecycle (install/uninstall via sc.exe, run mode)
│ ├── config.rs # Configuration loading and validation
│ ├── exports.rs # Export directory management and file handle resolution
│ ├── logging.rs # Log initialization and rotation
│ └── nfs/
│ ├── mod.rs # Unified NFS server (TCP + UDP, v3 + v4, TLS)
│ ├── nfs4.rs # NFSv4.1/4.2 protocol implementation (~4100 lines)
│ ├── protocol.rs # NFSv3 protocol implementation
│ ├── mount.rs # MOUNT protocol (v1/v3)
│ └── portmap.rs # PORTMAP / RPCBIND service
├── build.rs # Build script
├── config.example.toml # Example configuration
├── install.bat # One-click install script
├── uninstall.bat # One-click uninstall script
├── Cargo.toml # Package manifest
├── README_zh.md # Chinese README
└── README.md # This file
- Rust 1.70+ (install from rustup.rs)
- Windows 10/11 or Windows Server 2016+
- Visual Studio Build Tools (C++ workload)
cargo build --releaseThe binary is at target/release/rustnfssvc.exe.
If there is configuration file config.toml just under the same folder of rustnfssvc.exe, it will be used as default config.
Copy the example config and edit it:
copy config.example.toml "C:\ProgramData\RustNfsSvc\config.toml"Edit C:\ProgramData\RustNfsSvc\config.toml to set your export paths and client access rules.
Standalone mode (for testing):
rustnfssvc.exeAs a Windows Service (requires Administrator):
:: Install
install.bat
:: Start
net start rustnfssvc
:: Stop
net stop rustnfssvc
:: Uninstall
uninstall.batConfiguration is loaded from C:\ProgramData\RustNfsSvc\config.toml. See config.example.toml for a complete reference.
[nfs]
listen_address = "0.0.0.0:2049"
enable_v3 = true
enable_v4 = true
threads = 4
bind_ip = "0.0.0.0" # Bind to specific IP for security
max_connections = 128 # Global concurrent connection limit
max_conn_rate_per_ip = 60 # Per-IP rate limit (connections per 60s window)
enable_udp = true # Enable UDP (set false for production with TLS)
[tls] # SEC-015: TLS encryption
enabled = false
cert_path = "" # PEM certificate path (required when enabled)
key_path = "" # PEM private key path (PKCS8 or PKCS1 RSA)
[[exports.entries]]
path = "C:\\Shared"
alias = "shared"
allowed_clients = ["192.168.1.0/24"]
options = ["rw", "sync", "no_subtree_check"]
[logging]
level = "info"
file = "C:\\ProgramData\\RustNfsSvc\\logs\\rustnfssvc.log"
max_log_size_mb = 100
max_log_files = 10| Option | Description |
|---|---|
rw |
Read-write access (default) |
ro |
Read-only access |
sync |
Synchronous writes |
async |
Asynchronous writes |
no_subtree_check |
Disable subtree checking (better performance) |
insecure |
Allow connections from ports ≥ 1024 |
no_root_squash |
Allow root to access files as root |
RustNfsSvc supports built-in TLS encryption for NFS traffic over TCP. When enabled, the server uses rustls (ring backend) to encrypt all NFS/MOUNT/PORTMAP TCP connections.
-
Generate certificates — Create a PEM certificate and private key for the server:
# Using OpenSSL openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes \ -subj "/CN=nfs-server" -addext "subjectAltName=IP:192.168.1.1" # Convert key to PKCS8 (preferred by rustls) openssl pkcs8 -topk8 -nocrypt -in server.key -out server.key.pkcs8
-
Configure — Edit
config.toml:[tls] enabled = true cert_path = "C:/etc/rustnfssvc/server.crt" key_path = "C:/etc/rustnfssvc/server.key" # PKCS8 or PKCS1 RSA accepted
-
Disable UDP — TLS only works over TCP. Set
enable_udp = falsewhen using TLS. -
Restart — Restart the service for TLS to take effect.
Linux NFS clients do not natively support TLS. Use stunnel to create an encrypted tunnel:
On the client (Linux):
-
Install stunnel:
sudo apt install stunnel4 # Debian/Ubuntu sudo yum install stunnel # RHEL/CentOS
-
Create
/etc/stunnel/nfs.conf:[nfs] client = yes accept = 127.0.0.1:2049 connect = <server-ip>:2049 verifyChain = yes CApath = /etc/ssl/certs ; Or specify the server cert directly: ; CAfile = /path/to/server.crt
-
Start stunnel:
sudo systemctl start stunnel4
-
Mount via the local tunnel:
sudo mount -t nfs4 -o vers=4,minorversion=1 127.0.0.1:/<alias> /mnt/shared
Note: When using stunnel on both sides, the NFS mount address is always
127.0.0.1(the local tunnel endpoint), not the server's real IP.
If you prefer not to use the built-in TLS, you can also run stunnel on the server side to wrap the NFS port:
On the server (Windows):
-
Download stunnel for Windows.
-
Create
stunnel.conf:[nfs] accept = 2049 connect = 127.0.0.1:12049 cert = C:/etc/rustnfssvc/server.crt key = C:/etc/rustnfssvc/server.key
-
Configure RustNfsSvc to listen on the internal port:
[nfs] listen_address = "127.0.0.1:12049"
-
Start stunnel, then start RustNfsSvc. Stunnel will encrypt traffic on port 2049 and forward to the internal NFS port.
sudo mount -t nfs4 -o vers=4,minorversion=2 <server-ip>:/<alias> /mnt/sharedsudo mount -t nfs4 -o vers=4,minorversion=1 <server-ip>:/<alias> /mnt/sharedsudo mount -t nfs -o vers=3 <server-ip>:/<alias> /mnt/sharedls /mnt/shared
echo "hello from NFS" > /mnt/shared/test.txt ┌─────────────────────┐
Linux NFS Client ───│ NFSv4.2 (TCP/2049) │───┐
Linux NFS Client ───│ NFSv4.1 (TCP/2049) │───┤
Linux NFS Client ───│ NFSv3 (TCP/2049) │───┤
Linux NFS Client ───│ NFSv3 (UDP/2049) │───┤
└─────────────────────┘ │
┌─────────────────────┐ │
mount.nfs ──────────│ MOUNT (TCP/20048) │───┤
mount.nfs ──────────│ MOUNT (UDP/20048) │───┤
└─────────────────────┘ │
┌─────────────────────┐ │
rpcinfo ────────────│ PORTMAP (TCP/111) │───┤
rpcinfo ────────────│ PORTMAP (UDP/111) │───┤
└─────────────────────┘ │
▼
┌─────────────────┐
│ ExportsManager │
│ (C:\exports\...) │
└─────────────────┘
- Unified listener — A single TCP/UDP listener on port 2049 handles NFSv3, NFSv4.1, and NFSv4.2 requests, dispatching by RPC program version
- ExportsManager — Manages file handle resolution, directory enumeration, and file I/O against the local Windows filesystem
- Session management — NFSv4.1/4.2 sessions with slot/sequence tracking for exactly-once semantics
# Run in debug mode
cargo run
# Run tests
cargo test
# Format code
cargo fmt
# Lint
cargo clippy| Protocol | RFC | Status |
|---|---|---|
| NFSv3 | RFC 1813 | Supported |
| NFSv4.0 | RFC 3010 | Partial |
| NFSv4.1 | RFC 5661 | Supported |
| NFSv4.2 | RFC 7862 | Supported |
| MOUNT v1 | RFC 1094 | Supported |
| MOUNT v3 | RFC 1813 | Supported |
| PORTMAP v2 | RFC 1057 | Supported |
| Operation | Opcode | Status | Description |
|---|---|---|---|
| READ_PLUS | 68 | ✅ Supported | Enhanced read returning data/hole information |
| COPY | 60 | ✅ Supported | Server-side intra-server file copy |
| SEEK | 69 | ✅ Supported | Find next data or hole offset in a file |
| CLONE | 71 | ✅ Supported | Server-side file range clone (read+write) |
| ALLOCATE | 59 | Stub | Returns NOTSUPP |
| DEALLOCATE | 62 | Stub | Returns NOTSUPP |
| IO_ADVISE | 63 | Stub | Returns NOTSUPP |
| LAYOUTERROR | 64 | Stub | Returns NOTSUPP |
| LAYOUTSTATS | 65 | Stub | Returns NOTSUPP |
| OFFLOAD_CANCEL | 66 | Stub | Returns NOTSUPP |
| OFFLOAD_STATUS | 67 | Stub | Returns NOTSUPP |
| WRITE_SAME | 70 | Stub | Returns NOTSUPP |
| COPY_NOTIFY | 61 | Stub | Returns NOTSUPP |
Note: Stub operations return
NFS4ERR_NOTSUPP. COPY only supports intra-server copy; inter-server copy is not supported. CLONE is implemented as a simplified read+write (no BlockClone API). SEEK uses a simplified model (SEEK4_HOLE returns file size) since Windows does not expose sparse file hole information via standard APIs.