Skip to content

Open a port in the VPS firewall

4 steps · Checked against the API code 3 November 2026

A guide does one task from start to finish. Every endpoint, with all its fields and cases, is in the API reference.

Every VPS has a firewall on Hostup’s side, in front of the server. While its protection is off, as on a new VPS, every port the server listens on can already be reached. When protection is on, an incoming connection gets through only if an allow rule matches it. To open a port you add an allow rule, make sure protection is on and check the result. Step 1 shows which case you have.

  • An API key with the scopes read:vm and write:vm. The requests use the key as $HOSTUP_API_KEY (Quickstart). Keys and scopes
  • The ID of the VPS, vps_…. List VPS instances if you don’t have it.
  • The port your service listens on. To limit a rule to one address, you also need the address you connect from.
export VPS_ID="vps_…" # your VPS: List VPS instances

GET /api/v2/vps/{id}/firewall says whether protection is on, which rules exist and whether you can add one.

GET /api/v2/vps/{id}/firewall
curl "https://cloud.hostup.se/api/v2/vps/$VPS_ID/firewall" \
-H "Authorization: Bearer $HOSTUP_API_KEY"
Response 200
{
"available": true,
"reason": null,
"enabled": false,
"limits": { "maxRules": 100, "currentRules": 0, "remainingRules": 100 },
"rules": [],
"actions": {
"canAddRule": { "allowed": true, "reason": null },
"canToggleFirewall": { "allowed": true, "reason": null }
},
"…": "…"
}
  • enabled is true: protection is on. A port stays closed until a rule allows it. Go on with step 2.
  • enabled is false: protection is off. Read If protection is off below.
  • actions.canAddRule.allowed is false: reason says why. One reason is the limit of 100 rules. Delete a rule you no longer need first.
  • available is false: reason says why. While the VPS is still being set up, wait a little and read it again. If reason says the rules need support repair, contact Hostup support. Waiting does not help then.

Every port your server listens on can already be reached, including the one you want to open. An allow rule changes nothing until protection is on. If your port does not answer, look inside the server. A firewall there, such as ufw or firewalld, can block it. Or no service listens on the port. You can stop here.

Go on only if you want the firewall to keep every other port closed. Then add a rule in step 2 for each port the server must stay reachable on, not only the new one. Turn protection on in step 3.

POST /api/v2/vps/{id}/firewall adds one rule for incoming traffic. If you connect to the server over SSH, add your SSH rule first. This rule lets SSH in from one address only.

Replace 198.51.100.10 with the address you connect from. With the example address, step 3 locks you out of SSH.

POST /api/v2/vps/{id}/firewall
curl -X POST "https://cloud.hostup.se/api/v2/vps/$VPS_ID/firewall" \
-H "Authorization: Bearer $HOSTUP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "in",
"action": "ACCEPT",
"enabled": true,
"proto": "tcp",
"dport": "22",
"source": "198.51.100.10",
"description": "SSH from office"
}'
Response 201
{
"pos": null,
"type": "in",
"action": "ACCEPT",
"enabled": true,
"proto": "tcp",
"dport": "22",
"sport": null,
"source": "198.51.100.10",
"dest": null,
"description": "SSH from office",
"isSystem": false,
"editable": true
}

Then open the port for everyone. This rule has no source:

POST /api/v2/vps/{id}/firewall
curl -X POST "https://cloud.hostup.se/api/v2/vps/$VPS_ID/firewall" \
-H "Authorization: Bearer $HOSTUP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "in",
"action": "ACCEPT",
"enabled": true,
"proto": "tcp",
"dport": "443",
"description": "HTTPS from anywhere"
}'

The response is 201 with the new rule, in the same shape as above. The fields you choose:

  • enabled: send true. Without it the rule is stored switched off.
  • proto: tcp or udp for a rule with a port. It is required as soon as you set a port.
  • dport: the port on your VPS. One port (443), a list (80,443) or a range (8000-8100). A range comes back written as 8000:8100.
  • source: one IP address or a CIDR range, IPv4 or IPv6. Leave it out to allow everyone over both IPv4 and IPv6.

Add a VPS firewall rule explains every field.

  • All traffic from one address: send a source and no proto or dport.
  • Ping: send "proto": "icmp" with no port and no source. That one rule covers IPv4 and IPv6.

When enabled was true in step 1, protection is on. Go on with step 4. Otherwise turn it on with PUT /api/v2/vps/{id}/firewall/options. actions.canToggleFirewall in step 1 says whether you can call it now.

Every port without an allow rule closes, SSH, web and mail included. Add a rule for each of them in step 2 before this call. Keep enabled at true in every call. false switches off the whole firewall, not only protection. Protection goes on and off with inboundPolicy.

PUT /api/v2/vps/{id}/firewall/options
curl -X PUT "https://cloud.hostup.se/api/v2/vps/$VPS_ID/firewall/options" \
-H "Authorization: Bearer $HOSTUP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled": true, "inboundPolicy": "DROP"}'
Response 200
{
"enabled": true,
"inboundPolicy": "DROP",
"platformFilteringInbound": true,
"…": "…"
}

platformFilteringInbound true confirms that protection is on. It is the enabled you read in step 1. Here enabled is the firewall’s main switch. It is already true on a new VPS. Get VPS firewall options returns the same fields at any time.

Read the list again. Find your rules by description.

GET /api/v2/vps/{id}/firewall
curl "https://cloud.hostup.se/api/v2/vps/$VPS_ID/firewall" \
-H "Authorization: Bearer $HOSTUP_API_KEY"
Response 200
{
"enabled": true,
"rules": [
{
"pos": 0,
"proto": "tcp",
"dport": "443",
"source": null,
"description": "HTTPS from anywhere",
"editable": true,
"…": "…"
},
{
"pos": 1,
"proto": "tcp",
"dport": "22",
"source": "198.51.100.10",
"description": "SSH from office",
"editable": true,
"…": "…"
}
],
"…": "…"
}

Then connect to the port from outside, from an address the rule allows. A rule only lets the traffic reach the VPS. A service must listen on the port. A firewall inside the operating system, such as ufw or firewalld, can still block it.

The API is not behind the VPS firewall. Turn protection off from here. The switch in the client area sends the same.

PUT /api/v2/vps/{id}/firewall/options
curl -X PUT "https://cloud.hostup.se/api/v2/vps/$VPS_ID/firewall/options" \
-H "Authorization: Bearer $HOSTUP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled": true, "inboundPolicy": "ACCEPT"}'

Your rules stay stored. Add the rule you were missing as in step 2. Then turn protection on again as in step 3. The rules filter again as soon as you set DROP.

PUT and DELETE find a rule by its pos from the list. A position is not a fixed ID. A new rule goes in at the top, at position 0. Every rule already there moves down one place. The answer to an added rule has pos null. Read the list right before you change a rule. Change only rules whose editable is true.

PUT /api/v2/vps/{id}/firewall/{pos} replaces the whole rule. A field you leave out is cleared on the stored rule. enabled is the exception: leave it out and the rule keeps its current state. In step 4 the HTTPS rule is at position 0. This request replaces it to open port 80 next to 443:

PUT /api/v2/vps/{id}/firewall/{pos}
curl -X PUT "https://cloud.hostup.se/api/v2/vps/$VPS_ID/firewall/0" \
-H "Authorization: Bearer $HOSTUP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "in",
"action": "ACCEPT",
"enabled": true,
"proto": "tcp",
"dport": "80,443",
"description": "Web from anywhere"
}'
Response 200
{
"pos": 0,
"type": "in",
"action": "ACCEPT",
"enabled": true,
"proto": "tcp",
"dport": "80,443",
"sport": null,
"source": null,
"dest": null,
"description": "Web from anywhere",
"isSystem": false,
"editable": true
}

DELETE /api/v2/vps/{id}/firewall/{pos} removes a rule when you no longer need the port open. The response is 204 with no body.

DELETE /api/v2/vps/{id}/firewall/{pos}
curl -X DELETE "https://cloud.hostup.se/api/v2/vps/$VPS_ID/firewall/0" \
-H "Authorization: Bearer $HOSTUP_API_KEY"

After this delete the SSH rule moves up from position 1 to 0. The API has no call that moves a rule to another position. To change what a position holds, replace the rule there with PUT.

  • Outbound rules (type out) and entries of type group cannot be changed through this API. Their editable is false. While the firewall needs support repair (step 1), every rule shows editable false.
  • A firewall group you apply in the client area adds its rules as ordinary in rules. You can change and delete them here. They go in at the top of the list. The positions of your other rules move down.
  • The response to a changed ping rule shows proto as null. Read the list to see it as icmp.
  • Every call here is done when it responds. There is no job to follow.
  • No e-mail goes to the account holder. Nothing is invoiced and nothing costs money.
  • The Firewall tab of the VPS in the client area shows the same rules.
  • With protection on, replies to connections the VPS opened itself always get through. You need no rule for them.
  • 403 forbidden with requiredScopes: the key lacks write:vm (When a key is refused).
  • 400 invalid_request: a field in the body is wrong. errors[] names it with a pointer. A port without proto, an unknown field and REJECT as the action all end here. Fix the field and send the request again.
  • 422 invalid_request: dport is not a port, a list or a range of ports between 1 and 65535. A description over 128 characters ends here too. This response has no errors[]. Its detail only says the request is invalid. Check those two fields.
  • 404 vps_not_found: the ID is wrong or the VPS belongs to another account.
  • 404 not_found: there is no rule at that position. Read the list again and use the current pos.
  • 403 forbidden without requiredScopes on a change or delete: the position holds an out or group rule. Read the list again and pick a rule whose editable is true.

Next: Point a domain at your server