Connecting Aski to an ERP that isn't on the internet
If your ERP lives inside the company network and has no public address, Aski reaches it through an encrypted tunnel. To do that, a small program — Tailscale — is installed on one machine in that network.
Before you start
- The install key. If you don't have it yet, request it before you start. It works once and expires: that window is for installing it, not how long the access lasts.
- A machine on the ERP's network that is always on. It can be the ERP server itself or any other machine on the same network.
- Administrator rights on that machine, just to install.
- Outbound internet access from that machine, over port 443. Nothing has to be opened inbound, but if that segment has no internet access —or only reaches it through a proxy that asks for a username and password— tell us beforehand: it is the one thing that can stop the node from coming up.
What this does NOT do
- It does not open any inbound port. The node opens the connection outwards.
- It does not expose your ERP to the internet. It stays unreachable from outside.
- It does not modify your ERP. Nothing is installed inside it.
- It hands your credentials to no one. You type the ERP user and key into the app yourself.
Step 0 · Decide where the node goes
This decides everything else, so settle it before installing anything. There are two options and neither is better: it depends on whether you can install software on the ERP server.
Option A · On the ERP server itself (recommended)
- Simplest. No routes to approve, nothing to coordinate.
- It cannot clash with another customer. The address it gets is unique worldwide, so there is no possible ambiguity.
- Requires being able to install software on that server.
- The address you will use in Aski is the one Tailscale assigns, starting with 100. You get it in step 3.
Option B · On another machine on the same network
- For when you would rather not touch the ERP server. Any always-on machine on that network will do.
- That machine acts as a bridge: you have to tell it which network to reach. That is the subnet, and it goes in the command.
- When you finish you have to say so: that bridge is enabled on the Aski side.
- The address you will use in Aski is the ERP's internal IP (
192.168.x.xor similar), not the one starting with 100.
Important · with option B, a Linux bridge needs one extra command. Freshly installed it does not forward traffic: you have to enable forwarding. It is a single command, it is in the Linux section, and without it the connection fails on a timeout with no clue at all. This is measured, not a theoretical precaution.
The bridge can be Windows or Linux, either one, including with an ERP over HTTPS — the typical case being the SAP Business One Service Layer. The packet size adjustment that used to be needed on the bridge is now applied by Aski on its own end. On Windows, forwarding is enabled by Tailscale itself on install, so there is nothing to do there.
With all that, A is still preferable whenever it is possible: it has none of these steps, and
it also avoids another nuisance. If two different companies use the same internal network — and
192.168.1.0/24 is the most common in the world — it has to be disambiguated, and
with A that never happens. If you go with B, say which network you use so it can be checked
first.
What the subnet is, and how to work it out
Only needed for option B. It is the network where the ERP lives, written as "base address + slash + number":
192.168.1.0/24 (the usual one in offices) 10.0.0.0/24 172.16.5.0/24
To work it out, look at the ERP server's IP and change the last number to 0, adding
/24:
ERP is at 192.168.1.20 -> subnet is 192.168.1.0/24 ERP is at 10.0.5.44 -> subnet is 10.0.5.0/24
The /24 means "the 254 addresses of that network", which is how almost any office
is set up. If your network is bigger and you are not sure, pass on the ERP's IP and its netmask
to have it confirmed.
Required for option B: the ERP's internal IP and its port.
Installing on Windows Server / Windows 10 or 11
This is the usual case when the ERP is SAP Business One. You need the console just once: the Tailscale window does not accept install keys — only signing in with an account — and we do not want to create any account here.
- Download the installer from
tailscale.com/download/windowsand run it. Next, Next, Install. - When it finishes, do not open the Tailscale window and do not sign in. If something opened, close it. The connection is made with the key, not with an account.
- Open PowerShell as administrator: right-click the Start button → "Terminal (Admin)" or "Windows PowerShell (Admin)". Accept the permission prompt.
- Paste the command you were given and press Enter. It looks like this:
tailscale up --authkey=YOUR_KEY --hostname=aski-yourcompany --unattended
And like this if the node goes on another machine (option B), with the subnet at the end:
tailscale up --authkey=YOUR_KEY --hostname=aski-yourcompany \
--advertise-routes=192.168.1.0/24 --unattended
Important. --unattended is essential on Windows. Without it, Tailscale
stops when you sign out, and on a server that always happens: the connection would drop by
itself after a few hours, for no apparent reason.
If it worked it prints nothing. To check:
tailscale ip -4
It returns a single line with an address starting with 100. That is the sign it worked.
Installing on Ubuntu, Debian, RHEL, Rocky or another Linux
1. Install Tailscale (the script detects your distribution):
curl -fsSL https://tailscale.com/install.sh | sh
2. Connect it with your install key:
sudo tailscale up --authkey=YOUR_KEY --hostname=aski-yourcompany
And if the node goes on another machine (option B):
sudo tailscale up --authkey=YOUR_KEY --hostname=aski-yourcompany \
--advertise-routes=192.168.1.0/24
3. Check that it joined:
tailscale ip -4
4. And that the service starts with the system, so it survives a reboot:
sudo systemctl is-enabled tailscaled
It must answer enabled. If it answers disabled, turn it on with
sudo systemctl enable tailscaled. On Linux you do not need
--unattended: that is a Windows thing.
Option B only · the step that is missing
If the node goes on the ERP server itself (option A), skip this: you are done. What follows is for the machine acting as the bridge. Without this step the tunnel looks connected and the connection fails on a timeout. It is the failure that takes the longest to find, precisely because it gives no error.
Let the machine forward traffic. A bridge, by definition, passes packets that are not addressed to it, and Linux does not do that out of the box:
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-tailscale.conf sudo sysctl --system
It is written into /etc/sysctl.d/ on purpose, rather than with
sysctl -w: that way it is still set after a reboot. Check it with
sysctl net.ipv4.ip_forward, which must answer = 1.
After this you have to repeat the tailscale up from step 2 mentioning the
hostname as well, or it will error out; it is under "If something doesn't work".
If the tunnel goes down after somebody touches the firewall, the first thing to try is
sudo systemctl restart tailscaled. Reloading firewalld — or any
firewall-cmd --reload — wipes the rules Tailscale had put in the system, and from
that point on the node still shows as connected but no longer passes traffic. Restarting
Tailscale puts them back. It is the same symptom described above, and the most common reason for
a tunnel that had been working for weeks to stop all at once.
Before reporting that you are done, check from this same machine that the ERP answers, using check 7. If it does not answer from the bridge, it will not answer through the tunnel either, and the problem is in the internal network — not in Aski.
There is no longer any need to touch the packet size. If you followed an earlier version
of this guide that asked for an iptables rule with TCPMSS, you can keep
it or remove it: it makes no difference. That adjustment is now applied by Aski on its own end, so
there is nothing to configure on your server and nothing that gets lost on a reboot.
If the ERP runs in Docker
A container is started alongside it, sharing the ERP's network. Two details matter: the volume, because without it the node loses its identity on restart and has to be installed again; and the name, because without it the node shows up under the ERP container's own name and cannot be told apart from the others.
docker run -d --name tailscale \ --network container:YOUR_ERP_CONTAINER_NAME \ --cap-add NET_ADMIN --device /dev/net/tun \ -v tailscale-state:/var/lib/tailscale \ -e TS_AUTHKEY=YOUR_KEY \ -e TS_HOSTNAME=aski-yourcompany \ -e TS_STATE_DIR=/var/lib/tailscale \ tailscale/tailscale:latest
Last step · what you need to report
If you chose option A (node on the ERP server): nothing else. The node shows up on the Aski side by itself. Just say you finished and you will be given the address to use.
If you chose option B (node on another machine):
- Say so, because the bridge has to be enabled on the Aski side.
- Give the ERP's internal IP and its port. For example
192.168.1.20and8069.
Important. Until that bridge is enabled, the connection will not work even if everything else is right. It is a single click on the Aski side.
Creating the connection in Aski · field by field
In the app: Connections → New connection. These are the fields as they appear on screen:
ERP type
Odoo · SAP S/4HANA · SAP B1. Whichever applies.
Nickname
The name you will see for this connection in your list. It is just for you: use whatever helps you recognise it, like "Odoo production" or "SAP office".
"My ERP is not reachable from the internet" checkbox
You have to tick this box. It sits right below the URL field. It is what makes the app accept an internal address: without it, the app rejects it on purpose and will not let you save.
If you cannot see the checkbox, say so: it means the tunnel is not active yet, and it is enabled on the Aski side.
URL
Here goes the address left over from the installation, with the ERP's port:
Option A (node on the ERP server)
http://100.71.252.92:8069
^^^ whatever `tailscale ip -4` returned, plus the port
Option B (node on another machine on the network)
http://192.168.1.20:8069
^^^ the ERP's internal IP, plus the port
The port is the ERP's, the same one used inside the office: 8069 for Odoo by default, 50000 for the Business One Service Layer.
Important. It must be an IP address, not a hostname. A hostname would be resolved by the DNS on the Aski side, not on your network, and would point somewhere else or nowhere.
The next three fields — Database, User and API Key — change per ERP and are the ones that raise the most questions. They are explained step by step, with where to find each one in Odoo, Business One and S/4HANA, in the guide at aski.dev/en/credentials-guide. Here is the summary.
Database
The database name in Odoo — visible in the URL when you log in, like
?db=mycompany. In Business One it is the Company DB, something like
SBO_MyCompany. On S/4HANA this field does not appear.
User / login
The ERP user the queries will run as. Each person enters their own, not a shared one.
API Key
On Odoo: generated from your profile → Account Security → New API Key, and shown only once. On Business One: that SAP user's password. On S/4HANA: your instance's API Key.
Test and save
Press Test connection to check before saving, then Connect and save. If the test fails, see the last section of this guide.
Several people in the same company
The tunnel is installed once for the whole company. Each person who will use Aski creates their own connection in their own account:
- Same URL and same database for everyone.
- Their own ERP user and their own API Key.
- Everyone ticks the checkbox.
Nothing has to be reinstalled or reconfigured per person. And using individual credentials is not bureaucracy: it makes each person see exactly what their user sees in the ERP, no more and no less. With a shared user, everyone would see the same thing.
Cutting off access, whenever you want
Without asking us and with immediate effect, either of these:
- Turn off the node:
tailscale downon that machine, or uninstall Tailscale. - Disable the ERP user that Aski uses.
You can also ask for the key to be revoked and the access disappears.
Checks · the commands that save you an afternoon
On the machine where you are going to install the node. On Windows, PowerShell as
administrator; on Linux, a terminal with sudo. Each check answers a question
that, left unanswered, shows up halfway through the install.
1 · Does this machine reach the internet?
Test-NetConnection controlplane.tailscale.com -Port 443 # Windows curl -sI https://controlplane.tailscale.com | head -1 # Linux
Look for TcpTestSucceeded : True or an HTTP/2 200 reply. If it does
not, the node will not come up, and that is the first thing to ask infrastructure for. Nothing
needs opening inbound, only outbound.
2 · Is this the ERP machine, or just a machine on the network?
Get-NetTCPConnection -State Listen | Select-Object LocalPort | Sort-Object LocalPort Get-Service | Where-Object DisplayName -match "SAP|Odoo" # Windows sudo ss -lntp | grep -E ':(8069|8071|50000|443)' # Linux systemctl status odoo 2>/dev/null | head -3
If 8069 or 8071 (Odoo), 50000 (Business One Service Layer) or 443 (either of them behind a proxy) shows up among the ports, the ERP is here and yours is option A.
If the services only list "SAP Business One Client Agent", this is a user machine and
the ERP lives elsewhere. In Odoo the equivalent is having no odoo service and nothing
listening on 8069.
3 · So which machine is the ERP on?
Odoo: it is the address you use from the office. If it is a name rather than an IP, resolve it:
Resolve-DnsName erp.mycompany.local # Windows getent hosts erp.mycompany.local # Linux
Business One: from a machine with the client open, the established connections give it away:
Get-NetTCPConnection -State Established |
Where-Object RemotePort -in 30000,40000,50000 |
Select-Object RemoteAddress, RemotePort
The RemoteAddress you get is the server (30000 is the license server, 40000 the
SLD). It also shows in the client's login window, under "License server".
4 · Can I reach the ERP from here, and on which port?
Test-NetConnection YOUR_ERP_IP -Port 8069 # Odoo (or 443, or 50000 on B1) nc -vz YOUR_ERP_IP 8069 # Linux
YOUR_ERP_IP is the address from check 3. A True — or a
succeeded — settles it. If your ERP is on a different port, tell us: it has to be
authorised on our side, and if we don't know the connection fails with no detail.
5 · Your address and your subnet (option B only)
Get-NetIPAddress -AddressFamily IPv4 |
Select-Object IPAddress, PrefixLength, InterfaceAlias # Windows
ip -4 -br addr # Linux
An IP of 192.168.10.30 with PrefixLength 24 means the subnet is
192.168.10.0/24: the same address with the last number set to 0, and the slash
carrying that number. Ignore 127.0.0.1 and any Docker or Hyper-V adapters; you want
the real network card.
6 · Does your network use the same range as the tunnel?
Get-NetRoute -AddressFamily IPv4 | Select-Object DestinationPrefix # Windows ip -4 route # Linux
If anything between 100.64.x.x and 100.127.x.x shows up — some
corporate VPNs use it — tell us before installing: it collides with the tunnel's range and
is adjusted on our side, without touching your server. It is not common, but finding out
afterwards costs an afternoon.
7 · Test access to the ERP before touching the app
This validates the address, the port, the database, the user and the key in one go. If it answers here, the connection in Aski will go through.
Odoo — returns a number (the user id) if everything is right, or false if
the database, the user or the key do not match:
Invoke-RestMethod -Method Post -Uri "http://YOUR_ERP_IP:8069/jsonrpc" -ContentType "application/json" -Body '{"jsonrpc":"2.0","method":"call","params":{"service":"common","method":"authenticate","args":["YOUR_DB","USER","PASSWORD_OR_API_KEY",{}]},"id":1}'
Business One — returns a SessionId if everything is right. It also validates
that the user has a license assigned:
[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
Invoke-RestMethod -Method Post -Uri "https://YOUR_ERP_IP:50000/b1s/v1/Login" -ContentType "application/json" -Body '{"CompanyDB":"SBO_MyCompany","UserName":"USER","Password":"PASSWORD"}'
The Business One Service Layer is always HTTPS. With http:// it answers a
400 whose text says you are speaking plain HTTP to an SSL port. The first line is so PowerShell
accepts its self-signed certificate, which is normal in an on-premise install; without it you get
"could not establish trust relationship for the SSL/TLS secure channel", which is a problem with
neither the ERP nor Aski. In Odoo, by contrast, plain HTTP on 8069 is the norm inside the network.
And when you paste either command, check the line starts with Invoke: the first
letter gets lost more often than you would think.
8 · The database name
Odoo: it shows in the URL when you log in (?db=mycompany) and in the
database selector if the server hosts several. With only one, it can usually be left empty.
Business One: in the client, Choose Company, column "Database Name". It looks
like SBO_MyCompany. It is not the company's trading name: if you give us that,
the login fails with a message about credentials and the problem gets hunted where it isn't.
9 · What is usually missing on the ERP side
Odoo: the user's API Key, generated from their profile → Account Security → New API Key, and shown only once. And that this user has read access to whatever will be queried: Aski sees exactly what they see.
Business One: a license assigned — the Indirect Access type is the one meant for external applications and the cheapest, and you can see it under Administration → License → License Administration, column "Available" — plus read authorisation on Business Partners at the very least: without that module the connection never gets saved.
If something doesn't work
"The key is not valid" when running the command
Keys work once and expire. If you already used it or the window passed, ask for another one: it is generated on the spot.
I installed everything and Aski says it can't reach the ERP
- Check that the ERP responds from the machine where you installed Tailscale, at that same address and port. If it does not respond from there, it will not through the tunnel either.
- If the node is on another machine (option B): say so, the bridge still needs enabling.
- On Windows: check the command included
--unattended. - Check the URL includes the port and is an IP, not a hostname.
It won't let me save: it says the address is not valid
The "My ERP is not reachable from the internet" checkbox is not ticked.
It was working and stopped
Almost always the node's machine was switched off. Turn it on and it reconnects by itself; nothing has to be reinstalled and no new key is needed.
"tailscale" is not recognised as a command
Either it is not installed, or the PowerShell window was open from before you installed it and cannot see the new program. Close it and open another one as administrator, or call it by its full path:
& "C:\Program Files\Tailscale\tailscale.exe" up --authkey=YOUR_KEY --hostname=aski-yourcompany --unattended
I save the connection and it spins until it fails
This is the most common symptom of option B, and it has four causes. Go through them in this order, from the most frequent to the least:
- The bridge still needs enabling on our side. Tell us: it is one click.
- Forwarding is not enabled on the bridge machine ("the step that is missing").
sysctl net.ipv4.ip_forwardhas to say= 1. If it says= 0after you already set it, it was set withsysctl -wand was lost on the last reboot. - Somebody touched the firewall and wiped Tailscale's rules. This is the typical reason
a tunnel that had been fine for weeks stops all at once, and the most confusing one,
because the node still shows as connected. Fix it with
sudo systemctl restart tailscaled. - The ERP server is powered off or its service is not listening. The clue that tells
this apart from everything above: from the bridge itself,
curlto the ERP does not answer either.
"changing settings via 'tailscale up' requires mentioning all non-default flags"
This comes up when you add the subnet to a node that was already connected, and it is not a fault: Tailscale is warning you that you are leaving out a setting it already had — the hostname — and it stops before wiping it for you. The message itself prints the corrected command at the end:
sudo tailscale up --advertise-routes=192.168.1.0/24 --hostname=aski-yourcompany
If it works it prints nothing, apart from a warning about IPv6 that you can ignore.
It was working, somebody touched the firewall and it went down
Reloading or reconfiguring the firewall wipes Tailscale's internal rules. One command puts them back, with no reinstalling and no new key:
sudo systemctl restart tailscaled
If the bridge had the packet-size rule and it was not saved as permanent, put it back as well.
Business One: "rejected the login" or "check the URL and the credentials"
- The URL carries
https://and the port:https://IP:50000/b1s/v1. - The Company DB is the database name, not the company's.
- The user needs a license assigned and read access to Business Partners — without that module the connection will not save, and the message talks about credentials.
- The command in check 7 tells the three cases apart in 15 seconds.