---
title: "Go SDK — Network & firewall"
description: "Tenant networks and VM firewall rules with the Metalhost Go SDK."
url: "https://metalhost.net/docs/developers/guides/sdk-network"
---

# Go SDK — Network & firewall

`NetworkServiceClient` manages tenant L2 networks and per-VM firewall rules on public IPv4. Public IPs are allocated at VM create — no standalone attach RPC.

## Networks

Each project gets a default network per datacenter automatically. Create extra networks only when you need isolation:

```
net := networkv1connect.NewNetworkServiceClient(httpClient, base)
resp, err := net.CreateNetwork(ctx, connect.NewRequest(&networkv1.CreateNetworkRequest{
    ProjectName:    "projects/my-app",
    DatacenterName: "datacenters/us-dal-1",
    DisplayName:    "prod-net",
}))
```

Resource name: `projects/{p}/networks/{id}`. IPv6 /64 always allocated; optional IPv4 /24 private subnet.

```
net.ListNetworks(ctx, connect.NewRequest(&networkv1.ListNetworksRequest{
    ProjectName: project,
}))
```

## Firewall rules

Rules apply to a VM's public NIC. A default SSH rule (TCP/22) is seeded when the public NIC is first allocated; add explicit rules for HTTP, HTTPS, or any other inbound service.

```
vm := "projects/my-app/virtual-machines/web-1"
net.CreateFirewallRule(ctx, connect.NewRequest(&networkv1.CreateFirewallRuleRequest{
    ProjectName:    "projects/my-app",
    DatacenterName: "datacenters/us-dal-1",
    TargetVm:       vm,
    DisplayName:    "ssh from office",
    Direction:      "ingress",
    Sources:        []string{"203.0.113.10/32"},
    Ports: []*networkv1.PortMapping{{
        Protocol: "tcp", Port: 22,
    }},
}))
net.ListFirewallRules(ctx, connect.NewRequest(&networkv1.ListFirewallRulesRequest{
    ProjectName: "projects/my-app", TargetVm: vm,
}))
net.DeleteFirewallRule(ctx, connect.NewRequest(&networkv1.DeleteFirewallRuleRequest{
    Name: "projects/my-app/firewall-rules/rule-id",
}))
```

### Port ranges

```
Ports: []*networkv1.PortMapping{{
    Protocol: "tcp", Port: 30000, EndPort: 32767,
}}
```

### Model

- **Ingress only** — the firewall gates inbound from the internet. `CreateFirewallRule` rejects `egress`; use security groups for east-west policy.
- **Sources** — CIDR list (IPv4 or IPv6); empty = allow from anywhere
- **Additive** — rules compose; no ordering

> **applies to the public NIC**
>
> Firewall rules gate the VM's public NIC (IPv4 + IPv6). A private-only VM has no public NIC, so firewall rules don't apply — see [Go SDK — VMs](https://metalhost.net/docs/developers/guides/sdk-vms.md).

## What's next

- [Dashboard — Networks](https://metalhost.net/docs/dashboard/guides/networks.md)
- [Dashboard — Firewall rules](https://metalhost.net/docs/dashboard/guides/firewall.md)
- [Dashboard — Public IPv4](https://metalhost.net/docs/dashboard/guides/public-ipv4.md)
- [CLI → Network & firewall](https://metalhost.net/docs/developers/guides/cli-network.md)
