Before you start
This guide is general information about how we approach hosting security. It is not advice for your specific situation, and it is not a substitute for someone who knows your environment.
Every command is intended to be read-only, and written that way deliberately. You are nonetheless running them on your own systems at your own discretion. Read each one before you run it, particularly on anything carrying production traffic.
The section on data residency covers principles rather than current rule detail, because the detail moves. Nothing here is legal advice, and obligations differ by sector and jurisdiction. Check anything regulatory with your own advisers. MDCS accepts no liability for decisions taken on the basis of this guide.
01 · What is exposed
Most compromises at this scale begin with something reachable from the internet that was never meant to be. Not a sophisticated attack — a database port, an admin panel, a management interface left open when a firewall rule was widened during a deployment and never narrowed again.
What is listening, from the machine itself
Anything bound to 0.0.0.0 or :: is reachable from any interface. Anything bound to 127.0.0.1 is not reachable from outside the machine. That distinction is the whole exercise.
What is reachable from outside
The second list is deliberate: SSH, web, MySQL, PostgreSQL, Redis, MongoDB and Elasticsearch. The last four should almost never answer from the public internet.
Scan only systems you own or are authorised to test. Port scanning infrastructure belonging to somebody else is unlawful in most jurisdictions, and providers treat it as an abuse matter regardless of intent. Run this against your own address, from your own machine.
The pattern to look for
Firewall rules widen during incidents and rarely narrow afterwards. A rule opened at 2am to get a deployment working is still open a year later, and nobody remembers adding it. Reviewing the rule set on a schedule catches this; nothing else does.
Admin interfaces
Database administration tools, application admin panels, monitoring dashboards and CI interfaces are frequently published on the public internet with only a password in front of them. Each is a full-privilege route into the system.
- Bind them to localhost and reach them over SSH tunnel or VPN
- Where they must be public, restrict by source address and require multi-factor authentication
- An unguessable URL is not access control — it is visible in browser history, proxy logs and referrer headers
02 · Credentials and secrets
Credentials committed to a repository are the second common route in. Once a secret has been committed it exists in the history permanently, and removing it in a later commit does not remove it from the repository.
Checking what is in the history
If either returns something, treat the credential as disclosed and rotate it. Rewriting history does not help if the repository has ever been cloned, forked or mirrored.
| Where secrets go | Suitability |
|---|---|
| Environment variables from a file outside the repository | Adequate for a small deployment, provided the file is 0600 and owned by the service account |
| A secrets manager | Appropriate once more than one person or one machine needs them, and gives rotation and an access record |
| In the repository, encrypted | Workable with a maintained tool, but the decryption key still has to live somewhere |
| In the repository, in plain text | Disclosed to everyone with read access, permanently |
| In the application configuration, committed | The same, with the addition that it is easy to forget it is there |
Accounts
- Separate credentials per person. Shared accounts cannot be revoked without disrupting everyone.
- Multi-factor authentication on the hosting account before anything else. It is the account that controls every other account.
- Application database users with the permissions the application needs, rather than administrative rights.
- A record of which credentials exist and who holds them, so leaving is a defined process rather than an act of memory.
03 · Who can reach what
Two questions worth being able to answer at any point: who can reach the systems, and how long access survives after someone stops needing it.
Every key in authorized_keys is a person or a system that can log in. If any of them cannot be identified, remove it and see who asks.
Removing an unidentified key can interrupt an automated process. Where a system is in use, do this during a maintenance window and have console access available.
04 · Traffic controls
Two measures cover most of what a small application faces from automated traffic.
Rate limiting
Login endpoints, password reset, registration and anything expensive to serve should limit requests per address. Without it, credential-stuffing runs at whatever speed your server allows.
Test limits before applying them to production. A limit set too low will block legitimate use, and where several users share an outbound address — an office, a mobile network — they will appear as one source.
A web application firewall
A WAF filters common automated attacks before they reach the application. It is not a substitute for correcting the underlying issue, and it will occasionally block something legitimate. Run it in monitoring mode first and read what it would have blocked.
TLS
- Certificates from an automated issuer, renewed automatically. Expired certificates are among the more common self-inflicted outages.
- HTTP redirected to HTTPS, with HSTS once you are confident the redirect holds.
- Check the configuration against a public TLS testing service after any change.
05 · Backups
Backups are where the difference between an incident and a catastrophe is decided, and they are the item most often assumed rather than verified.
| Question | What matters |
|---|---|
| What | Three separate things get conflated: the database, user-uploaded files, and configuration. Code is in the repository. The other three often are not anywhere. |
| Where | A backup on the same server is not a backup. A snapshot in the same cloud account is half of one, since a compromised account reaches both. Off-server, and off-provider for anything you would genuinely miss. |
| Immutability | Ransomware and account compromise both look for backups. A backup a compromised credential can delete will not survive the event it exists for. Write-once retention, or a separate account with separate credentials. |
| How often | Anchored to a question rather than a number: how much data can you afford to lose — an hour, a day, a week? That answer is your recovery point objective. Choosing it deliberately is different from inheriting whatever the provider set. |
| Retention | Daily for a fortnight, weekly for a couple of months, monthly beyond. The reason is not storage cost: some compromises are discovered weeks later, and a two-day window means every backup held is already affected. |
| Testing | An untested backup is a hypothesis. Restore it somewhere, confirm the application starts, confirm the data is current, and time it — because that time is the real recovery window. |
The number worth writing down
How long a full restore takes, measured rather than estimated. Everything else in a recovery plan depends on it, and it is usually longer than expected — the download alone is often the largest part.
Where data is allowed to sit
Choosing a region costs nothing on day one and requires a migration to change afterwards, which is why it belongs in the initial design rather than a later review.
This section covers principles, not current rules
Data protection law changes, differs by sector, and depends on what data you hold and where your users are. What follows is the shape of the problem. The specifics need your own advisers.
Two distinct concepts
Data localisation requires data to be stored within a particular country. Transfer restriction permits data to move but conditions how. They are often discussed as though they were the same requirement; they are not, and the difference determines your architecture.
What is generally true
- India. The Digital Personal Data Protection Act does not impose general localisation. It permits cross-border transfer except to countries the government restricts. Hard localisation requirements are sectoral — payment system data under RBI rules is the most widely applicable example, with separate provisions for insurance and some government data.
- European Economic Area. The GDPR is not a localisation law either. It restricts transfers outside the EEA unless an adequacy decision applies or an appropriate safeguard such as standard contractual clauses is in place.
- Sector rules usually bind harder than general law. Finance, health, insurance and government contracts frequently carry obligations that are stricter than the national data protection regime, and they are where genuine localisation requirements are found.
- Contracts add obligations of their own. A client agreement may require data to remain in a jurisdiction regardless of what the law permits.
What to establish before choosing a region
Whose personal data you hold and where those people are. Which sector rules apply to your business. What your client contracts require. Whether your provider can guarantee a region for both primary storage and backups — backups being the part most often overlooked, since they frequently replicate elsewhere by default.
If something goes wrong
The order matters more than the speed. Most of the difficulty in a recovery comes from actions taken in the first ten minutes.
Preserve evidence before changing anything
Snapshot the disk, and copy the logs somewhere the affected system cannot write to. Cleaning first removes the record of how entry was gained, and that record is what prevents a repeat.
Contain
Take it offline, or restrict access to known addresses. A site that is unavailable is a smaller problem than one being actively used.
Rotate every credential
Hosting account, database, API keys, SSH keys, anything in the repository, anything a compromised process could read. Assume everything reachable from the affected system is disclosed.
Rebuild rather than clean
Rebuild from a known-good image and redeploy from source. Cleaning a compromised system relies on finding everything that was changed.
Restore data from before the compromise
Which requires knowing when it happened — which requires step one. Restoring to a point after the entry restores the problem with it.
Close the entry route before going back online
Otherwise the sequence repeats, usually within days, and the second occurrence is harder to explain than the first.
Check your disclosure obligations
Under DPDP, GDPR and various sector rules, breaches involving personal data carry notification duties with deadlines. Establish early whether they apply, because the clock is unlikely to start when you notice.
The decision to make in advance
Who has authority to take the system offline, who is called, and whether an external responder is engaged. Deciding this during an incident costs hours, and hours are the currency.
Staging in a recovery
Worth stating precisely, because the distinction is narrow and the assumption is common.
What staging can and cannot do
It can restore your application quickly. Where staging is at the same commit as production, it is a clean source for code, and pulling from it is a legitimate move.
It is not a data backup. It holds code, not current production data, and it is usually stale.
Check before you trust it. If entry was gained through the application, the same weakness exists in staging. Restoring from it without establishing that reinstates the route in.
Two rules that avoid most of this: staging never shares a database with production, and staging is not publicly reachable. Restrict it by address or put authentication in front of it — an unindexed URL is not access control.
Before you go live
| Check | Done when |
|---|---|
| Exposure | Only the ports you intend are reachable from outside, verified from a machine on another network |
| Admin interfaces | Behind VPN, tunnel or source restriction, with multi-factor authentication |
| Secrets | Nothing in the repository history; anything found has been rotated |
| Hosting account | Multi-factor authentication enabled |
| Accounts | One per person, application database user without administrative rights |
| TLS | Automated renewal working, HTTP redirected |
| Rate limiting | In place on login and other expensive endpoints, tested |
| Backups | Off-server, immutable, retention chosen deliberately |
| Restore | Performed once, timed, and the time recorded |
| Environments | Staging separate, not publicly reachable, no production data |
| Region | Chosen against your obligations, backups included |
| Incident plan | Written down: who decides, who is called, what happens first |