Networking

⏱ 8 min read 🔵 Intermediate Last updated: April 2026

Every BareMeta server lives inside one of your projects. Servers in the same project share an internal private network and can talk to each other directly. Servers in different projects are isolated from each other by default — the only way they reach each other is through explicitly exposed public connectivity.

💡  Quick model: One project = one private network. All servers in that project share it. Different projects don't see each other internally.

How networking works

When you create a server on BareMeta, two things happen:

This gives you a normal VPS path for web servers while still letting backend/database/internal servers launch without inbound public exposure.

VPN access during closed beta

During beta, WireGuard VPN is the recommended secure way to reach private BareMeta servers from your own device. Public IPv4 is available for servers that request it during creation, subject to limited address capacity.

What is WireGuard?

WireGuard is a lightweight VPN. It creates an encrypted tunnel between your device and BareMeta, so your laptop or workstation can reach your private servers as if it were connected to the same private network.

Use it when your server does not have a public IPv4 address, or when you want to manage private services such as SSH, databases, and internal dashboards without exposing them to the internet.

During beta, VPN credentials are issued per user. Creating them requires your account to belong to at least one active billable organisation with a saved payment method. If you belong to multiple organisations, the VPN is still a single user credential rather than an organisation or project-specific credential.

The VPN gives your device an address in the 10.200.0.0/24 range and routes BareMeta private networks such as 10.10.x.0/24 through the tunnel. Once connected, use the private IP shown in the dashboard to reach your server.

# Check the tunnel on Linux
sudo wg show

# Check the BareMeta VPN gateway
ping -c 3 10.200.0.1

# Check your project gateway and server private IP
ping -c 3 10.10.101.1
ping -c 3 10.10.101.19
💡  How to connect: Open the VPN Access tab, generate WireGuard credentials, import the downloaded config into the official WireGuard client, then connect. The private key is shown only once. If you lose the config, revoke and recreate the VPN credentials.
⚠️  VPN access does not bypass your server's own firewall. If a service is blocked by UFW or is listening only on localhost inside the VM, the VPN will not make that service reachable.

Projects are private networks

A project on BareMeta is more than a folder for organising your servers. It's also a network boundary:

💡  Use projects to mirror real trust boundaries. Frontend + database + cache for one app? Same project. Two different customer environments? Two projects.

Servers in the same project

If you create three servers — say web-01, db-01, and cache-01 — in the same project, they'll get internal IPs that look something like:

web-01    10.10.42.10
db-01     10.10.42.11
cache-01  10.10.42.12

From web-01, you can reach the database directly:

# From web-01
psql -h 10.10.42.11 -U appuser mydb

# Or via Redis on cache-01
redis-cli -h 10.10.42.12

This traffic stays entirely inside your project's network. It doesn't touch the public internet and doesn't need any firewall rules to be opened. It just works.

⚠️  Same project = same trust zone. If one server in a project is compromised, others in the same project are reachable on internal IPs. For sensitive workloads, run host-level firewalls (UFW) on each server even within a project, or split into separate projects.

Servers in different projects

Each account starts with a single project named default, and all your servers go in there. That works for the vast majority of workloads — frontend, backend, database, cache all happily sharing one private network.

If you need a second project for environment separation (e.g. Staging vs Production) or to isolate a sensitive workload, contact support during the closed beta and we'll provision it for you. Once you have multiple projects, servers in different projects cannot reach each other on internal IPs — the platform blocks all internal traffic between projects by default. Communication between them happens via public IPs, the same way an external service would reach them.

Public IPs and what they mean

⚠️  Closed beta note: Public IPv4 uses the real datacentre pool and availability is limited. The default beta policy is one public IPv4 per user/project; additional public IPv4 addresses require operator approval.

An assigned public IPv4 address is dedicated to that server while the assignment remains active. The dashboard will only show a public address once it is actually assigned; launch-time assignment may appear shortly after first boot rather than instantly.

If you later want to swap public IPs between servers (e.g. blue/green deployments where you keep DNS pointing at the same IP), use the Reassign action in the Public IPs tab. To return an IP to the pool, use Release.

Practical implications:

What's open and blocked by default

Inbound and outbound traffic on your server is governed by two things: BareMeta's platform-level rules (which apply to all servers), and the host-level firewall you configure inside your server (UFW, etc.).

Platform-level — applies to every server

DirectionPort / ProtocolStatusWhy
Outboundtcp/25 (SMTP)BlockedSpam prevention. See Sending email below.
Outboundtcp/465, tcp/587 (SMTPS / submission)OpenAuthenticated mail submission to your relay of choice.
Outboundeverything elseOpenStandard outbound traffic — HTTP, HTTPS, DNS, SSH, NTP, etc.
InboundanyControlled by assignment and rulesA public IP must be assigned and routing/firewall sync must be active before inbound traffic can reach the server.

Host-level — your server's own firewall

Once a server is reachable from the internet, host-level firewalling is still your responsibility. Enable UFW with sensible defaults and open only the ports your workload needs. We cover this in detail in Securing your server.

Sending email from your server

Outbound traffic on port 25 (the port mail servers use to talk to each other) is blocked by default. This is standard practice across every reputable cloud provider and protects the IP reputation of the platform from compromised servers being used for spam.

⚠️  If you've configured Postfix, Sendmail, or any mail server to deliver mail directly, it will fail to send. Use a relay instead.

The right way to send mail

Use a transactional email relay. They handle the actual mail delivery from their own warmed-up reputation IPs, which gives you better deliverability than any cloud server's IP can ever achieve. Your server connects to the relay over port 587 or 465 (both open) using credentials you configure.

Popular options:

Configure your application or local mail daemon to connect to the relay's submission endpoint:

# Example — Python smtplib via Mailgun
import smtplib
from email.mime.text import MIMEText

msg = MIMEText("Hello from BareMeta")
msg["Subject"] = "Test"
msg["From"] = "you@yourdomain.com"
msg["To"] = "recipient@example.com"

with smtplib.SMTP_SSL("smtp.mailgun.org", 465) as smtp:
    smtp.login("postmaster@mg.yourdomain.com", "your-api-key")
    smtp.send_message(msg)

If you genuinely need direct port 25 access

Some legitimate use cases (e.g. running a mail server for an established domain with proper SPF/DKIM/DMARC and a clean sending history) need direct outbound :25. Contact support with details of your domain and intended sending volume — we can review and unblock case-by-case.

DDoS protection

BareMeta is backed by a UK datacentre provider with 24/7 onsite operations, redundant rack power, diverse connectivity, and provider-level network protection.

Baseline on-demand network-layer DDoS mitigation is included via our upstream datacentre provider, subject to provider limits and fair use. It is designed for volumetric attacks against the network path before traffic reaches your server.

Higher-capacity always-on protection may be available by agreement for workloads that need stronger guarantees. Exact thresholds, pricing, and filtering behaviour depend on the datacentre package active on your service.

💡  Application-layer attacks (slow loris, HTTP flood targeting your app logic) need application-layer defences — e.g. rate-limiting in your reverse proxy, Cloudflare in front of your origin.

Common setups

Single-server app

One server, one project. The default. Everything runs on one machine, you reach it via its public IP, you configure UFW to expose just :22 + :80 + :443. Simplest possible setup.

Web tier + database tier

Two servers in the same project. Web server has UFW open on :22 + :80 + :443. Database server has UFW open on :22 only — and the database listens on its private IP for connections from the web server. The database is invisible from the public internet.

# On db-01, configure PostgreSQL to listen on the private IP only
# In /etc/postgresql/16/main/postgresql.conf
listen_addresses = '10.10.42.11'

# In pg_hba.conf — only allow connections from the web tier's private IP
host    mydb    appuser    10.10.42.10/32    scram-sha-256

Staging vs production

Two projects: Staging and Production. Identical server layout in each. Servers across projects can't talk internally — staging accidents can't bleed into production data. If your CI needs to deploy from one to the other, do it over public IPs with proper auth.

Multi-customer separation

One project per customer. Each customer's data lives in its own private network, completely isolated from other customers at the platform level. A compromise in one customer's environment cannot scan or pivot to another customer's servers internally.