Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to bind the gateway API socket to localhost? Answer: No 😂 #173

Open
goodboy opened this issue Jun 2, 2022 · 11 comments
Open

Comments

@goodboy
Copy link

goodboy commented Jun 2, 2022

Seems like kind of wild I have to ask this, but the jts.ini doesn't have this option so I'm assuming it has to be set in one of the XML configs?

I find it pretty odd no one has asked this question here and I'm not finding a lot web searching 😂

@rlktradewright
Copy link
Member

I really don't understand what you're asking.

IBC can configure the port it should Gateway should listen on for API connections. But it always accepts API connections from localhost.

@goodboy
Copy link
Author

goodboy commented Jun 2, 2022

Right, but right now the gateway will accept TCP connections on the public ip for a host, sure the gateway might internally filter those connections - reject the TCP connect messages, but ideally you can have the socket .bind() call inside the gateway only bind to local host (127.0.0.1).

To see this simply nmap scan any host public non-localhost ip that the gateway is running on.

To clarify the thinking: ib code is proprietary blob; getting guaranteed socket connection filtering via the OS network stack is much more obviously secure.

@rlktradewright
Copy link
Member

By default Gateway will only accept connections from localhost. You can configure other IP addresses that it will allow to connect via the Trusted IP address list in the API settings.

However note that you can't use IBC to set the Trusted IP address list.

So this has nothing whatever to do with IBC. Why are you even discussing it here?

Your statement about 'clarifying the thinking' is anything but a clarification...

@goodboy
Copy link
Author

goodboy commented Jun 2, 2022

So this has nothing whatever to do with IBC. Why are you even discussing it here?

Because I would assume y'all being the authors of this great project might have come across this question before. Normally I'd expect a project like this to support such questions about the functionality of the underlying software being managed; my bad if that was a poor assumption.

IMO if it's possible to make ib apps bind to localhost by default it should also be a setting at the least recommended here and possibly configured if there is a way.

Your statement about 'clarifying the thinking' is anything but a clarification...

Not sure what you mean? Do you understand how berkley sockets work and the API for it? Further what I'm asking is pretty normal, If you don't plan to make a socket network accessible outside for the use of IPC on the local host then you would not normally bind to the * (everything) address but, ib apps are doing this.

@lbx2022
Copy link

lbx2022 commented Jun 2, 2022

Right, but right now the gateway will accept TCP connections on the public ip for a host, sure the gateway might internally filter those connections - reject the TCP connect messages, but ideally you can have the socket .bind() call inside the gateway only bind to local host (127.0.0.1).

To see this simply nmap scan any host public non-localhost ip that the gateway is running on.

To clarify the thinking: ib code is proprietary blob; getting guaranteed socket connection filtering via the OS network stack is much more obviously secure.

Simply add a firewall rule to block all inbound connections to your gateway's port since you're connecting to your gateway locally. This isn't related to ibkr at all, let alone ib_insync.

@goodboy
Copy link
Author

goodboy commented Jun 2, 2022

@lbx2022 yes, but I'm not asking how to filter sockets, i'm asking does anyone know how to make the app bind to local host 😂

Obviously, there are a variety of ways to work around an app not allowing configuration of it's bind address but I'm not asking for a workaround. I'm asking is there a way to configure this?

@rlktradewright
Copy link
Member

No there is no way to configure this via IBC. As you've already observed, Gateway is a proprietary blob and we have no control over what's in it. We work with what we get. Feel free to contact IB and ask them to provide an option for binding to localhost only, but good luck with that.

The bottom line is that you can completely control who can connect to Gateway via the options in the API settings.

@goodboy
Copy link
Author

goodboy commented Jun 3, 2022

No there is no way to configure this via IBC. As you've already observed, Gateway is a proprietary blob and we have no control over what's in it.

Indeed 😿

The bottom line is that you can completely control who can connect to Gateway via the options in the API settings.

Agreed, except I guess the tinfoil i normally adhere to says, well this means ib can DOS their own socket at any time if they know the filter code mechanics 😂

However note that you can't use IBC to set the Trusted IP address list.

On this note, I noticed in the XML configs for and ibg.xml (but note the first section ApiSettings was all on one line) that you seem to be able to set this?

<ApiSettings
  varName="api" dde="false" readOnlyApi="false"
  allowOnlyLocalhost="false" socketClient="false"
  autoOpenOrdDonwload="true" port="4006" includeFxPositions="true"
  prepareDailyPnl="true" includeContinuousUpdateChanges="true"
  sendMessagesInEnglish="false" sendMessagesTranslated="true"
  logLevel="2" useNegativeAutoRange="true"
  overridePrecautionaryConstraints="true" bypassBondWarning="false"
  bypassYtwWarning="false" bypassCalledBondWarning="false"
  bypassSameActionPairTradeWarning="false"
  bypassFlaggedAccountsWarning="false"
  bypassPriceBasedVolatilityRiskWarning="false"
  bypassUsStocksMarketDataInSharesWarning="false" masterClientID="-1"
  acceptLargeSize="false" showApiMsg="true" includeMktData="false"
  createApiMsgLogFile="false" showIBGConsole="true"
  aPINotAllowedShownAfterDenyAPI="false" slowBufferTimeout="30"
  syncAccounts="false" proportionalAllocation="false"
  disableAutoClose="false" multichartNetDoNotShowTime="0"
  multichartDoNotShowTime="0" verifiedAppPortRangeStart="7000"
  verifiedAppPortRangeEnd="8000" timeOfVerifiedAppShutdown="0"
  portOfVerifiedAppShutdown="0" exposeEntireTradingSchedule="true"
  splitInsuredDepositFromCacheBalance="false"
  sendZeroPositionsForTodaysOpeningOnly="false"
  encodeMessagesInAscii7="true"
  useAccountGroupWithAllocationMethods="true"
  sendMarketDataInLotsForUSStocks="false">
</ApiSettings>
  <ListOfStrings varName="trustedIPAddresses">
    <String>127.0.0.1</String>
  </ListOfStrings>

So if modifying that ListOfStrings xml sequence actually works couldn't IBC control this?

update:
further example from code on github:
benjamintboyle/interactive-brokers-gateway@3c32f66#diff-84f652177a81e4ca1d442086a8c147bf7263d4913eb1ee101f4bd84c5b4f7568R92

@goodboy
Copy link
Author

goodboy commented Jun 3, 2022

Also a further btw, if anyone wants to use @lbx2022's method but at an even lower level using ip rule here is the setting for an api port of 4002:

ip rule add blackhole iif <net_iface_name> from 0.0.0.0/0 dport 4002


Update:

An even better way with no net iface info required:
ip rule add not unicast iif lo to 0.0.0.0/0 dport 4002

I've verified that one can't be picked up on an nmap scan.

@rlktradewright
Copy link
Member

@goodboy
Yes of course you can modify the xml to set anything that would normally be set via the Gateway configuration UI.

So why doesn't IBC do this:

  1. I've said this a thousand times, but I suppose I'll have to say it again: the purpose of IBC is NOT to serve as an alternative mechanism for configuring TWS/Gateway. It is simply to automate some aspects of usage which cause inconvenience to normal users, like entering username and passwords. OF course if you look through config.ini you'll see that it does quite a bit more than just login credentials, but it's pretty much all to do with convenience. It's worth pointing out that there are some stupid out-of-the-box defaults for TWS/Gateway which mean that if you want to run them in a Docker image they won't be usable without some additional configuration (for example 'read only api' is set to true, which for the Gateway in particular is stupid since it's rare for anyone to use Gateway without a full read-write API connection). So some settings have been included in config.ini to allow minimal operation under Docker without involving manual intervention.
  2. There's no need. There are perfectly good configuration facilities in TWS/Gateway: much better to provide a way to access those mechanisms and persist the xml file.
  3. Fiddling with low-level files is always risky. It's bad enough that IB can break IBC by changing a dialog structure (fortunately it doesn't happen often these days). Being at their mercy over the xml structure is a step too far.
  4. In the case of the Trusted IP address list, most people who run gateway remotely (especially in a Docker environment running Gateway with no settings persisted) use IP tunnelling to map API connections though to localhost, so there is no need for this list.
  5. There's no easy way to actually locate the xml files, since they're in a user-dependent folder with a silly unpredictable name.

My suggestion to people wanting to run a 'private' Gateway or TWS instance under Docker (or even just on a remote server) has long been to include the full Jts directory tree containing their personal settings in their image, and make provision for that to be persisted so that config changes are carried forward between sessions.

And this is one thing I would want to see in any 'official' Docker image: the provision of a persisted settings store. This would give the ability to use TWS/Gateway under Docker in the same way as you'd use them on your desktop.

@goodboy goodboy changed the title Is there a way to bind the gateway API socket to localhost? Is there a way to bind the gateway API socket to localhost? Answer: No 😂 Jun 3, 2022
@goodboy
Copy link
Author

goodboy commented Jun 3, 2022

And this is one thing I would want to see in any 'official' Docker image: the provision of a persisted settings store. This would give the ability to use TWS/Gateway under Docker in the same way as you'd use them on your desktop.

Sounds good. I have a near ready prototype for this that I would like to eventually propose here too you in an effort toward #67 but it still needs some finessing and hardening. I'll probably present something minimal within the next couple weeks and then we can work through whether y'all would like to stamp and offer it as an image for distribution.

@rlktradewright btw thanks again for all your patience with my questions. I really appreciate all the work you've done and i'm hoping we can keep this space supportive of making ib's apps less of a headache to use 😎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants