OnRconConnection
OnRconConnection is called when a client attempts to open an RCON connection to the server, before the connection is accepted or authenticated. Returning a non-null value rejects the connection.
object OnRconConnection(System.Net.IPAddress Address)Parameters
| Parameter | Type | Description |
|---|---|---|
Address | System.Net.IPAddress | The IP address of the remote client opening an RCON connection. Use it to match against allow/deny lists or to log who is connecting. |
Return value
Return null to allow the connection to proceed to the ban and password checks. Return any non-null object to reject the connection: the socket is closed without being registered as an RCON client.
How it works
The hook fires in two places in the RCON listener. First, in RConListener.ProcessConnections, right after the server accepts a TCP socket and resolves its RemoteEndPoint: returning non-null here closes the socket immediately. Second, in Facepunch.Rcon.Listener.OnConnection, where returning non-null skips the password check and client registration path entirely, so the socket is never promoted to an authenticated RCON client.
The single parameter is a System.Net.IPAddress; ToString() gives the familiar dotted IPv4 (or IPv6) string you can compare against config entries. Because the hook runs before authentication, treat the address as untrusted: an attacker can connect from any source IP.
You cannot narrow the parameter to a different type here, so declare it exactly as IPAddress. Returning null lets the normal path continue (ban check, password check, registration). Persist any bookkeeping (connection counts, blocklists) through Oxide data or config rather than in-memory-only state if it must survive restarts. Keep the handler fast; it runs on the connection-accepting path.
Example plugin: Block RCON connections from non-allowed IPs
using System.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Rcon Ip Filter", "RustPluginGenerator", "1.0.0")]
[Description("Restricts RCON connections to a configurable list of IP addresses.")]
public class RconIpFilter : RustPlugin
{
private const string PermAdmin = "rconipfilter.admin";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Allow list of IP addresses")]
public List<string> AllowList = new List<string> { "127.0.0.1" };
[JsonProperty("Allow all when allow list is empty")]
public bool AllowWhenListEmpty = true;
}
protected override void LoadDefaultConfig() => config = new PluginConfig();
protected override void LoadConfig()
{
base.LoadConfig();
try
{
config = Config.ReadObject<PluginConfig>();
if (config == null) throw new Exception();
}
catch
{
PrintWarning("Configuration file is invalid, using defaults");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void SaveConfig() => Config.WriteObject(config);
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Denied"] = "Connection from {0} was rejected by the RCON IP filter.",
["Added"] = "Added {0} to the allow list.",
["Removed"] = "Removed {0} from the allow list.",
["Missing"] = "You must specify an IP address.",
["NotListed"] = "{0} is not in the allow list.",
["ListHeader"] = "Allowed RCON addresses: {0}"
}, this);
}
private string Msg(string key, string userId = null, params object[] args) =>
string.Format(lang.GetMessage(key, this, userId), args);
private void Init()
{
permission.RegisterPermission(PermAdmin, this);
}
private object OnRconConnection(IPAddress address)
{
if (address == null) return null;
string ip = address.ToString();
if (config.AllowList.Count == 0 && config.AllowWhenListEmpty)
return null;
if (config.AllowList.Contains(ip))
return null;
return true;
}
[ChatCommand("rconip")]
private void CmdRconIp(BasePlayer player, string command, string[] args)
{
if (player == null || !permission.UserHasPermission(player.UserIDString, PermAdmin)) return;
if (args.Length == 0)
{
SendReply(player, Msg("ListHeader", player.UserIDString,
config.AllowList.Count == 0 ? "none" : string.Join(", ", config.AllowList)));
return;
}
string action = args[0].ToLower();
if (action != "add" && action != "remove")
{
SendReply(player, Msg("ListHeader", player.UserIDString,
config.AllowList.Count == 0 ? "none" : string.Join(", ", config.AllowList)));
return;
}
if (args.Length < 2)
{
SendReply(player, Msg("Missing", player.UserIDString));
return;
}
string ip = args[1].Trim();
if (!IPAddress.TryParse(ip, out _))
{
SendReply(player, Msg("Missing", player.UserIDString));
return;
}
if (action == "add")
{
if (!config.AllowList.Contains(ip)) config.AllowList.Add(ip);
SaveConfig();
SendReply(player, Msg("Added", player.UserIDString, ip));
}
else
{
if (!config.AllowList.Remove(ip))
{
SendReply(player, Msg("NotListed", player.UserIDString, ip));
return;
}
SaveConfig();
SendReply(player, Msg("Removed", player.UserIDString, ip));
}
}
}
}The plugin keeps a configurable allow list of IP addresses. On start it registers the rconipfilter.admin permission and reads the list from config. When OnRconConnection fires, it converts the address to a string, checks the allow list, and returns a non-null marker object (here true) to reject anything not listed. If AllowWhenListEmpty is left at its default, an empty list disables filtering so you are not locked out. Chat commands let permitted admins add, remove, and list entries; changes are saved to config immediately. The command bypasses the filter only for addresses already permitted, so adjusting the list remotely requires an allowed connection.
Common use cases
Restrict RCON to known admin IPs
Maintain an allow list and reject every other address before the password is even checked, reducing brute-force exposure on your RCON port.
Temporary lockout after repeated failures
Track connection attempts per address and reject addresses that exceed a threshold, then clear them on a timer.
Audit RCON connection sources
Record each connecting address with a timestamp to a data file so you can review who has been probing your RCON port.
Pitfalls
No authentication at this point
The address is the only information available; anyone connecting passes through this hook. Do not treat a connection as proof of admin identity.
Returning non-null is the block signal
Unlike many hooks where null means cancel, here returning any non-null object rejects the connection. Returning
truefor a disallowed IP is the usual pattern.It fires twice per connection attempt
Both
RConListener.ProcessConnectionsandFacepunch.Rcon.Listener.OnConnectioncall the hook, so your handler may run twice for one client. Avoid side effects that double-count unless you account for it.
Build a plugin with OnRconConnection
Describe what should happen and get a compiled plugin that uses this hook.
Edit the prompt on the next screen. 2 free plugins a month, no card.
Last updated Oct 26, 2026. Found a mistake? Email support@rustplugingenerator.com.
Build a plugin with OnRconConnection
Generate