UPnPumpkin v0.0.7
Port forward ports on the router with UPnP or NAT-PMP so players can connect from the internet. Other plugins can request port mappings through UPnPumpkin.
See the plugin guide and API reference on the documentation site.
Installation
Put upnpumpkin.wasm from the plugin's GitHub release in your server's plugins/ folder and restart. Hot reload cannot ask for permissions, so the first load needs a restart.
What it does
Players outside your home network can only connect if your router forwards the server's ports to this machine. UPnPumpkin asks the router to do that, with UPnP or NAT-PMP, so you don't have to log in to it:
- It opens the Java Edition port (TCP 25565) and the Bedrock Edition port (UDP 19132). Change them in
config.tomlif your server listens elsewhere. - Ports are leased: the router forgets them if the server dies, they are renewed at half the lease time, and they are closed again when the server stops.
- When this machine already has a public address (a VPS or dedicated server) there is nothing to open, and
/upnp statussays so. /upnp statusshows the router that was found, its public address and every port.
It can't help when:
- the router has UPnP and NAT-PMP turned off (many do by default; look for "UPnP" in its settings),
- your provider shares one public address between customers (carrier-grade NAT), which the plugin detects and reports because nobody can connect in through it,
- the machine sits behind a second router, or runs in a container on a network that doesn't pass multicast (set
router.upnp_searchto the router's address in that case).
Anyone on your network can use UPnP, so only run this where you trust the network.
Unsupported routers
Some routers never work, or misbehave when asked, so UPnPumpkin recognizes them and stays away from them. It works out the make and model from the device description a UPnP router gives about itself and, for routers that answer no UPnP search at all, from their web interface. It does this before it sends the router anything to open a port.
When it finds one of these routers, nothing is opened and:
- the server log gets one warning when the plugin starts,
/upnp reloadfails with an error,/upnp statusshows the reason in red.
Forward the ports in the router's settings instead. These are the routers it is turned off for:
| Make | Models | Why |
|---|---|---|
| Telekom | All models | Telekom routers (Speedport) do not support UPnP or NAT-PMP. |
The list is BLOCKED_ROUTERS in src/blocklist.ts, and this table is generated from it. If your router is on it by mistake, or you know one that should be, open an issue.
For plugin authors
Other plugins can ask UPnPumpkin for a port over Pumpkin's plugin messages. The messages and a client live in the @pumpkin-plugins/upnpumpkin-api package, which BedrockAddonManager uses for its web server:
import { MappingWatcher, openUrl, PortMapClient } from '@pumpkin-plugins/upnpumpkin-api';
import { ipcSend } from '@pumpkin-plugins/plugin-kit/ipc';
const watcher = new MappingWatcher(
new PortMapClient(ipcSend),
{ key: 'web', protocol: 'tcp', port: 8123, description: 'My plugin' },
(state) => console.log(openUrl(state) ?? state.kind), // http://203.0.113.7:8123 once it works
Date.now
);
watcher.start(); // asks at once and keeps asking
// call watcher.tick() once per game tick, and watcher.stop() when doneIt copes with UPnPumpkin loading later or not being installed (state.kind is unavailable). The port is closed when the watcher stops, or after five minutes without a request. The router search itself is the @pumpkin-plugins/port-mapping package, which any plugin can use directly.
Permissions
Pumpkin asks for these on the server console the first time the plugin loads.
| Permission | Why |
|---|---|
fs.read.data | Read the plugin config in its data folder. |
fs.write.data | Create and update the config. |
network.udp.bind | Receive the answers of routers to UPnP searches and NAT-PMP requests. |
network.udp.outgoingdatagram | Search for routers (UPnP) and talk to them (NAT-PMP). |
network.tcp.connect | Send UPnP commands to the router's control URL. |
http.outbound | Check Pumpkin Market for plugin updates. |
Commands
| Command | Description | Permission | Default access |
|---|---|---|---|
/upnp status | Show the router that was found and every port that is open or being opened | UPnPumpkin:command.upnp.status | operators (level 3) |
/upnp reload | Reload config.toml and update the open ports | UPnPumpkin:command.upnp.reload | operators (level 3) |
Configuration
Settings live in plugins/data/UPnPumpkin/config.toml. The plugin creates the file if needed, adds settings from the schema and removes settings no longer defined there. Values for existing settings are preserved.
| Option | Type | Default | Description |
|---|---|---|---|
router.upnp | boolean | true | Look for routers that speak UPnP. |
router.nat_pmp | boolean | true | Look for routers that speak NAT-PMP. |
router.lease_seconds | integer | 3600 | How long the router keeps a port open without hearing from the plugin. It is renewed at half this time and closed again when the server stops. |
router.upnp_search | string | "239.255.255.250:1900" | Where UPnP searches are sent. The default is the multicast address every router listens on. Set the router's own address (for example "192.168.1.1:1900") when multicast is blocked on your network. |
router.nat_pmp_gateway | string | "" | The router to use for NAT-PMP, as "address:5351". Empty means the first and last address of the local network are tried. |
java.enabled | boolean | true | Open the Java Edition port. |
java.port | integer | 25565 | Port of the Java Edition listener. |
bedrock.enabled | boolean | true | Open the Bedrock Edition port. |
bedrock.port | integer | 19132 | Port of the Bedrock Edition listener. |
plugins.allow_requests | boolean | true | Let other plugins ask for ports to be opened, for example BedrockAddonManager for its pack downloads. They are closed again when the plugin stops asking. |
plugins.max_requests_per_plugin | integer | 16 | How many ports each plugin may keep open at once. Every plugin has its own limit. |
A fresh install gets this file:
# UPnPumpkin configuration.
# This file is managed by the plugin: when it starts, settings that were added are written here with
# their defaults and settings that were removed are dropped. Your values are kept; comments you add
# are not. Changes apply after `/upnp reload` or a server restart.
# How the router is found and how long it keeps the ports open.
[router]
# Look for routers that speak UPnP.
upnp = true
# Look for routers that speak NAT-PMP.
nat_pmp = true
# How long the router keeps a port open without hearing from the plugin. It is renewed at half this
# time and closed again when the server stops.
lease_seconds = 3600
# Where UPnP searches are sent. The default is the multicast address every router listens on. Set
# the router's own address (for example "192.168.1.1:1900") when multicast is blocked on your
# network.
upnp_search = "239.255.255.250:1900"
# The router to use for NAT-PMP, as "address:5351". Empty means the first and last address of the
# local network are tried.
nat_pmp_gateway = ""
# The Java Edition port (TCP).
[java]
# Open the Java Edition port.
enabled = true
# Port of the Java Edition listener.
port = 25565
# The Bedrock Edition port (UDP).
[bedrock]
# Open the Bedrock Edition port.
enabled = true
# Port of the Bedrock Edition listener.
port = 19132
# Requests from other plugins.
[plugins]
# Let other plugins ask for ports to be opened, for example BedrockAddonManager for its pack
# downloads. They are closed again when the plugin stops asking.
allow_requests = true
# How many ports each plugin may keep open at once. Every plugin has its own limit.
max_requests_per_plugin = 16