Cashflow Engine – MEIC & METF Strategy Database
Free trial
BlueprintUpdated

Securing your VPS

A rented Windows VPS arrives with Remote Desktop open on the default port and the default admin name. Eight steps to close that, plus the VPN endgame.

OptionsApp needs an always-on Windows machine, which in practice means a VPS — a rented Windows server on a public IP address. Every rented Windows server ships the same way: Remote Desktop reachable on the default port 3389, under the default account name Administrator. That is how you get in to set it up, and it is a reasonable state to hand a customer. It is not the state to leave it in.

Closing it takes about fifteen minutes with the tools already on the machine. Best done on day one, before you install TWS. If your VPS is already running, it is the same fifteen minutes — see Already running? for the one thing you have to plan around.

This is Windows and hosting configuration, not Cashflow Engine software. Your provider's documentation is the source of truth for their control panel and console. The steps below are the field-tested sequence our community arrived at on a Windows Server 2025 VPS; the exact menus differ slightly by provider and Windows version.

The idea in one line

Automated login attempts against a rented Windows server look for port 3389 and try the name Administrator. Take away both and they have nothing to aim at. That is the whole strategy, and it needs no extra software.

Blocking individual addresses is not part of it — that is whack-a-mole, the addresses rotate daily. Nor is restricting Remote Desktop to your own IP a good default here: you will want to reach this machine from a phone, from a hotel, from a connection whose address changed overnight, and a rule that assumes a fixed address is a rule that eventually locks you out at the worst moment. The endgame for anyone who wants it airtight is a VPN (Tailscale on the VM, Mac and phone) with Remote Desktop closed to the outside entirely — that is the last step, a quiet afternoon of its own once the eight below are done. The eight steps are what you do first, and they work from anywhere.

Before you start

Open your provider's VNC / rescue console once and confirm it works. It is in your customer panel, it does not go through Remote Desktop, and it is the way back in if a typo locks you out. Every step below is recoverable if that console works — and not if it doesn't. Check it now, not later.

Two conventions for the commands that follow:

  • 49317 is an example port. Pick your own number between 10000 and 60000, and use the same number in all three places it appears. Don't reuse the one printed here — a port everyone in one community shares is a port worth scanning for.
  • mpadmin is an example account name. Pick your own. Avoid admin, root, trader, user — those are on the same guess list as Administrator.

Run everything in PowerShell as Administrator on the VM.

Already running? Pick the window

Nothing here depends on a fresh machine — the eight steps are identical on a VPS that has been trading for a year. One thing to plan around: step 5 reboots the server, which closes TWS and OptionsApp with it.

So:

  • Do it outside market hours, with no open positions. A weekend is the comfortable choice; any evening works.
  • Afterwards, check TWS came back and reconnected — log in, confirm the DATA panel is green and OptionsApp shows a live connection before the next session. The connection checklist is the fast way to confirm it.
  • Your TWS auto-restart setting survives the reboot, but verify it anyway while you are in there; a machine that has been up for months is a machine whose settings nobody has looked at in months.

Steps 1–4 and 7–8 change nothing about a running automation. Only the reboot and the client update (step 6) need your attention.

The eight steps

1. Open the firewall for the new port — before you switch to it

Order matters. The rule goes in first; otherwise the reboot in step 5 leaves you with Remote Desktop listening on a port nothing is allowed to reach.

New-NetFirewallRule -DisplayName "RDP Port 49317" -Direction Inbound -Protocol TCP -LocalPort 49317 -Action Allow

Expect a small table describing the new rule (Enabled: True, Direction: Inbound, Action: Allow). The first call can take 10–30 seconds.

2. Move Remote Desktop to the new port

Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name PortNumber -Value 49317

No output means it worked. The change only takes effect on the reboot in step 5.

A port change on its own is noise reduction, not a security boundary — a scan finds an open port soon enough. It removes the bulk of untargeted traffic; steps 3 and 8 are what actually protect the account.

3. Rename Administrator, and renew its password

Rename-LocalUser -Name Administrator -NewName mpadmin

No output. The new name applies immediately, including at the VNC console.

Renaming beats creating a second admin and disabling the built-in one: on a VPS the built-in account is often the only way in, and disabling it is a genuine lockout risk. Renaming keeps exactly one account and simply removes the half of the guess that was free.

Then replace the password:

Set-LocalUser -Name mpadmin -Password (Read-Host -AsSecureString "New password")

The prompt is masked. Don't paste a password into a chat, a forum or a script.

On choosing it: long beats complicated. Four or five random words — 20+ characters — is stronger than ten characters of punctuation, and you can actually type it on a phone. Generate it in a password manager, use it nowhere else.

Keep your current session open until you have connected from a second device with the new password. That open session is your fallback if you typo it.

4. Read it back before you reboot

Three checks. If both ports agree and the new name is there, the reboot is safe.

Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name PortNumber
netsh advfirewall firewall show rule name="RDP Port 49317"
Get-LocalUser | Where-Object { $_.SID -like '*-500' } | Select-Object Name, Enabled

Why netsh and not Get-NetFirewallRule here: after the rename, in the same session, Get-NetFirewallRule returns error 0x80070534. The rule itself is fine — only that cmdlet is upset. netsh reads it correctly.

5. Reboot

Restart-Computer -Force

Your Remote Desktop session drops immediately — that is expected. The machine is back in one to two minutes.

6. Point your clients at the new port

In the Remote Desktop client on Mac, iPhone or iPad, edit the saved connection: PC name <IP>:49317, username your new account name, and the new password.

The certificate warning appears again on the first connection, because the new port is a new entry as far as the client is concerned. Accept it — and don't dawdle: that dialog times out after roughly 45 seconds.

7. Turn on the provider's own firewall — and let only Remote Desktop through

This is the step most people don't know exists. Your provider almost certainly offers a firewall in the customer panel, in front of the machine — and it is often not switched on. (On Strato it is under Server → Firewall; other providers have the same thing under a different name.)

It is better than the Windows firewall for this, for two reasons: it discards unwanted packets before they reach the VM — the Windows firewall can only reject them after the machine has already received and processed them — and its rules live in the panel rather than inside the VM, so you can always get at them even when you can't log in.

Create the rule first, then activate the firewall, or you lock yourself out.

FieldValue
NameRDP (free text)
ProtocolTCP — not ANY
IPv4 / IPv6IPv4
Source IP / CIDR0.0.0.0/0
Port range start / endboth 49317 — start = end means exactly this one port

0.0.0.0/0 means "from anywhere", and that is deliberate: you connect from changing addresses. The protection is the port, the account name and the lockout in step 8, not a source-address filter.

One rule is all you need. TWS, Windows Update and time sync are all outbound connections, which the firewall permits anyway. What must not be open:

  • 3389 — the old Remote Desktop port.
  • 445 / 135 / 139 — Windows file sharing. This is the classic ransomware path and has no business facing the internet.
  • 5985 / 5986 — Windows Remote Management.
  • 7496 / 7497 — the TWS API port. This one is specific to our setup and matters more here than anywhere else: anything that can reach it can place orders, with no password in the way. OptionsApp and TWS run on the same machine and talk over localhost, so there is nothing to gain by opening it. Keep Allow connections from localhost only ticked in the TWS API settings as well.

Test the Remote Desktop connection after activating. From outside, the machine should now answer on nothing but your chosen port.

8. Extend the account lockout to the admin account — and defuse the 42-day trap

Windows Server 2025 already locks an account after 15 failed attempts for 10 minutes. The built-in administrator account is exempt from it — and stays exempt after you rename it. That exemption is why a renamed-but-otherwise-default server still accepts unlimited guessing against its one real account, and switching it off is the single most valuable line in this list.

In secpol.msc → Account Policies → Account Lockout Policy, set Allow Administrator account lockout to Enabled. It applies immediately, no reboot.

Do this after step 3. Enabling lockout on an account whose name is still being guessed at means the account sits permanently locked; once the name is one only you know, the lockout is free protection.

The price: mistype your password 15 times — or leave a device reconnecting with an old saved password — and you are locked out for 10 minutes, then free again. Update every client to the new password first.

Now the 42-day trap, which will otherwise bite you six weeks from today. A fresh Server 2025 sets Maximum password age: 42 days. You just changed the password in step 3; six weeks later it expires, and Remote Desktop with Network Level Authentication will not let you change an expired password — the login simply fails. You end up back at "it doesn't work", with nobody attacking anything.

net accounts /maxpwage:unlimited /minpwlen:14

Expect "The command completed successfully." A single long password from a password manager that never expires is safer here than one that ambushes you every six weeks; the minimum length keeps the never-expiring part honest.

Three more settings while you're in there

Not part of the eight, but they belong to the same fifteen minutes:

  • Every power timeout off. A fresh Windows VPS switches the display off after 10 minutes. OptionsApp reads the paused screen as a freeze and fires an internal restart — in bad cases dozens of times a day, and you will not see it happen. Set the timeouts to Never:

    powercfg /change monitor-timeout-ac 0
    powercfg /change standby-timeout-ac 0
    powercfg /hibernate off
    

    That covers the three that matter on a server. The full set, the read-back and the GUI path — including the classic Power Options page that keeps reading 10 minutes after Settings already says Never — are in Power settings.

  • Windows Update on, with a fixed weekly maintenance window outside 09:30–16:15 US/Eastern. An update that installs and waits for a restart mid-session is the classic way to find TWS gone at 15:27. Put it in the same slot as the weekly manual IBKR login that TWS auto-restart requires anyway (see Keep it connected) so it is one recurring appointment rather than two.

  • One machine, one job. Keep the VPS to TWS and OptionsApp. No browsing, no downloads, no unrelated software, no extra accounts. A box with a small, known set of programs is one you can reason about.

Confirm it worked

Three checks, a day after the change.

From your Mac or a Linux machine, the old port should be silent:

nc -z -v -G 5 <IP> 3389

Expect "Operation timed out". A refused connection or a banner means something is still listening there.

On the VM, count the failed logons of the last hour — this is how you confirm the new configuration is actually doing its job:

(Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=(Get-Date).AddHours(-1)} -ErrorAction SilentlyContinue).Count

After the change this should read 0, or a single digit if you have been fat-fingering your own password.

And the TWS API port should be local-only:

netstat -an | findstr "7497"

It should be bound to 127.0.0.1, not 0.0.0.0.

If something goes wrong

Log in through the provider's VNC console — with the new name; if that fails, with Administrator, since one of the two is current. Open PowerShell as Administrator and reverse it:

Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name PortNumber -Value 3389
Rename-LocalUser -Name mpadmin -NewName Administrator
Restart-Computer -Force

Everything is then as it was. The extra firewall rule does no harm; remove it with Remove-NetFirewallRule -DisplayName "RDP Port 49317" if you want it gone.

The last step: no open port at all

Everything so far still leaves one port open, and an open port is findable. On the VPS this guide was written from, a scanner found the new port within 30 minutes and tried the name Administrator 201 times before giving up — it failed only because that account no longer existed. The port change keeps out the mass; it does not keep out the thorough. Account name, password and lockout are the actual protection.

The way to stop relying on them is to stop offering a port to the internet at all: a VPN between your own devices, with Remote Desktop reachable only through it. This guide uses Tailscale — free for up to 100 devices and 3 users, nothing to configure on a server, WireGuard underneath.

This is not an anonymising VPN like NordVPN. Tailscale connects your own devices to each other, as if they shared a home network. Your normal browsing is untouched and nothing is routed through anyone else.

Tailscale's own documentation is the source of truth for its apps and admin panel. The sequence below is what this setup needed; menu names move.

Order is everything: build the new way in, prove it from two devices, and only then close the old one. The provider-firewall rule from step 7 stays exactly where it is until the very end — it is your way back.

1. Create the account, sign in on Mac and phone

Create an account at tailscale.com — via Apple, Google, Microsoft or GitHub. There is no separate Tailscale password, which has one consequence worth knowing before you start: every device must sign in through the same provider. Pick a different one on the second device and it lands in a second, empty account that cannot see the first.

Install the Tailscale app on your Mac and iPhone/iPad, sign in, switch it on.

2. Sign the VM in — without typing anything on the VM

Install Tailscale for Windows on the VM, then in PowerShell:

tailscale login

It prints a link, https://login.tailscale.com/a/…. Copy it — don't retype it. It is valid for a few minutes only, and a transposed l/1 just gives you a 404. Paste it into the browser on the Mac that is already signed in, then Connect. Your Remote Desktop client passes the clipboard between the VM and the Mac, so the copy carries across.

Then read back the VM's address inside the VPN:

tailscale ip -4

Expect something like 100.x.y.z.

3. Turn on "Run unattended"

Tailscale icon in the system tray → right-click → Preferences → Run unattended → Yes.

This runs Tailscale as a service, so the VM stays on the VPN after you log off and across reboots. Without it, the VM drops off the VPN the first time you log out — which, on a machine you have just made reachable only over the VPN, is a lockout. Don't skip it, and don't leave it until after step 4.

4. Prove it, then close the old way in

Log off the VM — do not shut it down. In your Remote Desktop client, create a new bookmark alongside the old one: 100.x.y.z:49317. The port is unchanged; only the address is different.

Connect from the Mac. Then connect from the iPhone over mobile data, with Wi-Fi switched off — that second test is the one that proves you are arriving through the VPN rather than through your own network.

Only once both work, rebuild the step-7 firewall: in the provider panel, delete the rule for the Remote Desktop port. Leave the firewall itself active — now with no inbound rule at all. Tailscale needs none; it builds its tunnel from the inside out. The firewall from step 7 stops being a gatekeeper and becomes a closed door.

Then confirm the port is really gone. From your Mac or a Windows PC, with Tailscale switched off — otherwise the test runs through the tunnel and proves nothing — and against the public IP, not the 100.x.y.z one:

nc -z -v -G 5 <IP> 49317

Expect "Operation timed out". On a Windows PC:

Test-NetConnection -ComputerName <IP> -Port 49317

Expect TcpTestSucceeded : False (the "Ping … failed" warning above it is normal). From the internet the machine now answers nothing at all. Switch Tailscale back on afterwards.

If the test still succeeds, the provider rule has not taken effect yet — check the panel, saving there takes a few minutes.

5. Two things to finish

Disable key expiry on the VM. Tailscale makes a device re-authenticate every 180 days. On an unattended server that means it silently drops out of the VPN one day, with no warning and — now that the port is shut — no other way in. In the admin panel under Machines, on the VM: "…" → Disable key expiry.

Delete the old bookmarks that point at the public IP, on every device. They lead nowhere now, and keeping them around only produces a confusing failure at the worst moment.

A work computer where you can't install Tailscale? The compromise is a provider-firewall rule for the Remote Desktop port that admits only that one fixed office IP — the narrow version of the source filter this guide otherwise argues against, and reasonable precisely because it is an exception rather than your only route. For the rest of the internet the port stays shut.

If Tailscale itself gets stuck

The provider's VNC console is still the emergency exit and never depended on any of this. And the provider-firewall rule you deleted takes about a minute to recreate in the panel — no connection to the VM required.

What this does and doesn't cover

These eight steps close the front door: the machine stops being findable by the traffic that sweeps the whole internet for default Windows servers. For a box with a live broker connection on it, that is the part that matters, and it costs fifteen minutes.

They are not a complete server-hardening programme. A determined, targeted attempt is a different problem, and the honest answer to it is the VPN step above — Remote Desktop closed to the outside entirely. Nor do these steps touch the accounts behind the machine: your IBKR credentials, two-factor authentication on the IBKR account itself, and your OptionsApp password are separate defences and deserve the same attention.

Setup checklist

  • ☐ Window picked outside market hours, no open positions (if already running)
  • ☐ Provider's VNC / rescue console opened and confirmed working
  • ☐ Own port number chosen (10000–60000) and own account name chosen
  • ☐ Firewall rule for the new port created — before the port change
  • ☐ Remote Desktop port changed in the registry
  • ☐ Administrator renamed; password replaced with a 20+ character passphrase
  • ☐ Read-back done: both ports agree, new name present
  • ☐ Rebooted; clients updated to <IP>:<port> and the new password
  • ☐ Provider-panel firewall: rule created, then firewall activated
  • ☐ Nothing open but the new port — not 3389, 445/135/139, 5985/5986, 7496/7497
  • ☐ Allow Administrator account lockout enabled
  • ☐ net accounts /maxpwage:unlimited /minpwlen:14 run
  • ☐ Power timeouts set to Never (why)
  • ☐ Windows Update window fixed outside 09:30–16:15 US/Eastern
  • ☐ Verified: 3389 times out from outside, event 4625 count at 0
  • ☐ TWS back up, DATA panel green, OptionsApp reconnected

Optional, and a separate sitting — the VPN step:

  • ☐ Tailscale account created; Mac and phone signed in via the same provider
  • ☐ VM signed in; tailscale ip -4 returns a 100.x.y.z address
  • ☐ Run unattended enabled — before anything is closed
  • ☐ Connected over 100.x.y.z from the Mac and from the phone on mobile data
  • ☐ Provider-panel rule for the Remote Desktop port deleted, firewall still active
  • ☐ Verified with Tailscale off: the public IP times out on the port
  • ☐ Disable key expiry set on the VM; old public-IP bookmarks deleted everywhere

Get the weekly 0DTE research email

Research notes and product updates, straight to your inbox. Unsubscribe anytime.

Disclaimer

Cashflow Engine is analytics and educational software — not financial advice, and not an investment adviser, broker, or signal service. It issues no buy or sell recommendations and never holds or manages your money. Trading options carries substantial risk, including the loss of your entire investment. All backtests, simulations, and performance figures are hypothetical, are shown for research purposes, and do not indicate future results. Do your own research, understand the risks, and consult a licensed professional where appropriate. Your account, your decisions, your responsibility.

Cashflow Engine · terminal@cashflowengine.io