In short
SQL Server 2025 ships with much stronger default security than 2022 — mandatory TLS 1.3 encryption, PBKDF2 password hashing, RC4 disabled, TLS 1.0/1.1 deprecated. But three things still need manual hardening on every Raff Server install: replace the self-signed certificate with a real one (Let's Encrypt works), disable the sa account and use least-privilege application logins, and enable SQL Server Audit so you actually know who logged in and what they did. This guide walks through each step with T-SQL examples, verified on a live SQL Server 2025 Standard Developer install on Windows Server 2025.
Who this guide is for
You've installed SQL Server 2025 on a Raff Server (see our SQL Server 2025 install guide) and you want to take it to a production-ready security posture before exposing the instance to applications, internal users, or the internet. This guide is written for MSPs and DBAs who deploy SQL Server for clients and need a defensible, documented hardening checklist they can re-use.
If you're a solo developer doing local dev work, you can skim Part 2 ("What you still need to do") and skip the Audit and certificate sections — they're for production deployments.
What you'll need
- A working SQL Server 2025 install on a Raff Windows Server, with the Database Engine running and reachable from your admin workstation
- Sysadmin access to the SQL instance — either via
sa(which we'll disable as part of this guide) or a Windows-authenticated admin (preferred, what we'll use throughout) - PowerShell admin access to the Raff Server — we use
Invoke-Sqlcmdfor most steps - A domain you control if you plan to follow Part 2's certificate replacement section — Let's Encrypt cannot issue certs for IP addresses or for Raff's rDNS hostnames, you need your own DNS-resolvable name
- Estimated time: 60-90 minutes for the full hardening pass
About the examples in this guide
Several commands in this guide contain placeholder values you must substitute before running. They are intentionally documentation-friendly (RFC 5737 IPs, example domains, obvious password patterns) so they will not work in production without replacement:
| Placeholder | Replace with |
|---|---|
customeracme.com / sql.customeracme.com | A domain you actually own and control |
203.0.113.10/32, 198.51.100.42/32 | Your admin/office public IP (find via ifconfig.me or ipinfo.io) |
TempStrongPassword2026!ReplaceMe | A 16+ character password generated by your password manager |
StrongMasterKeyPassword2026!, StrongCertPrivateKeyPassword2026! | Distinct strong passwords stored in your password manager and a backup off-server |
PASTE_THUMBPRINT_HERE_LOWERCASE | The actual SHA-1 thumbprint of your certificate (from Get-ChildItem Cert:\LocalMachine\My) |
<Raff Server public IP> | Your Raff Server's actual public IPv4 address |
If a command produces a "login failed" or "address invalid" error after you run it, double-check that you substituted every placeholder. Copy-pasting verbatim will not work.