IPSEC to Fortigate

Hey guys,

I’m currently having major issues setting up an IPSEC vpn to remote Fortigate router.

My setup
SXT Lite5 ac cpe running pppoe on wlan for internet
Lan is on ether1 with dhcp 192.168.0.0/24

IPSEC Configuration
SRC. Address 0.0.0.0/0
DST. Address 0.0.0.0/0
SA SRC. Address my-public-ip
SA DST. Address remote-public-ip

Protocol:ESP
Tunnel: ticked
Level: unique
Action: Encrypt

Firewall Nat
SRC. Address 192.168.0.0/24
Action SRC-NAT
To Addresses: my-public-ip

The tunnel will phase2 establish and I can ping remote webserver from CPE, but not from LAN PC

Below is remote VPN requirments for Fortigate;

Internet Key Exchange Configuration
Authentication Algorithm: SHA-512
Encryption Algorithm: AES-256-CBC
Lifetime (seconds): 86400
Phase 1 Negotiation Mode: MAIN
Perfect Forward Secrecy: Diffie-Hellman Group 20

IPsec Configuration
Protocol: ESP
Authentication Algorithm: SHA-512
Encryption Algorithm: AES-256-CBC
Lifetime (seconds): 3600
Mode: Route Based
Perfect Forward Secrecy: Diffie-Hellman Group 20

Diffie-Hellman Group 2 on mikrotik I have ecp384


Firewall rules;
/ip firewall filter
add action=accept chain=input comment=“allow IPsec NAT” dst-port=4500 protocol=udp
add action=accept chain=input comment=“allow IKE” dst-port=500 protocol=udp
add action=accept chain=input comment=“allow l2tp” dst-port=1701 protocol=udp
add action=accept chain=input comment=“allow pptp” dst-port=1723 protocol=tcp
add action=accept chain=input comment=“allow sstp” dst-port=443 protocol=tcp
add chain=input comment=“ipsec-ah” proto=ipsec-ah action=accept
add chain=input comment=“ipsec-esp” proto=ipsec-esp action=accept


If anyone can help with the solution for this problem, I will reward them.

What does /ip firewall nat print say?

Hey Sindy,

/ip firewall nat print
0 ;;; Wan Src-Nat
chain=srcnat action=src-nat to-addresses=my-public-ip src-address=192.168.0.0/24 log=no log-prefix=“”

Well, so all packets with source address from the LAN subnet will be src-nated to the public IP. Is that what you actually want, i.e. will the Fortinet machine route the response packets to that address via the IPsec tunnel?

The point is that the packets are matched by IPsec policy only after the src-nat rule is executed. Your IPsec policy does not care about src-address as you have set it to 0.0.0.0/0, so these packets will be sent towards the Fortinet, but the way back may be a problem.

The other (independent) issue is that your policy will also handle any packets coming back as also its dst-address is set to 0.0.0.0/0. So you should restrict the src-address of the policy to just 192.168.0.0/24 or just the public IP, in accord with the src-nat setting, depending on whether you want the Fortinet to see the actual LAN addresses or the public one.

If the Fortinet insists that you use 0.0.0.0/0 as both src-address and dst-address of the policy, you’ll have to place an exception policy in front of the policy associated to the SA, which will prevent the latter from redirecting packets for devices on your LAN back to the tunnel:

/ip ipsec policy print
/ip ipsec policy add place-before=0 action=none src-address=0.0.0.0/0 dst-address=192.168.0.0/24 place-before=0

Hi Sindy,

Thank you for your very helpful detailed reply, I added /ip ipsec policy add place-before=0 action=none src-address=0.0.0.0/0 dst-address=192.168.0.0/24 place-before=0
I can now open up webserver in browser with the IP of the webserver, but when I try to go to the actually webserver domain address, I get Server not found and webpage wont load.

IPSEC Gateway a.a.a.a
Webserver b.b.b.b
I was told that the traffic to web server should be routed out IPSEC Gateway

IPSEC Gateway a.a.a.a
Webserver b.b.b.b

I Added routes to /IP Routes
Dst. address a.a.a.a Gateway WAN
Dst. address b.b.b.b Gateway WAN

I can ping webserver and my PC on the Lan, but cant load up any website or the webserver domain, only the webserver IP I can reach from the web browser

Any help would be much obliged

What you are missing so far is that vanilla IPsec (which you use) works independent of the routing, or better to say it supersedes the routing after the routing has been done. Unlike other VPN types, IPsec doesn’t create a tunnel interface which you could use as a gateway. So it only needs that the normal routing would send the packet somewhere, not to a blackhole. And then, after all routing and firewall operations including NAT have been done, IPsec policies inspect the packets and if they like them, they steal them, encrypt them and send them through their respective IPsec tunnels called security associations.

So in your case where the main IPsec policy says that everything (dst-address=0.0.0.0/0) shall be set via the tunnel, the specific route you have added for the web server, i.e. dst-address=b.b.b.b gateway=WAN, doesn’t change anything about that behaviour.

And as you can open the web page on the server using the browser if you put there its IP address, but cannot open it if you put there its domain name, I would assume that the issue is with DNS operation. So you should first try to ping the server’s domain name, and if it fails either, it is definitely a DNS issue. I would expect that your DNS servers are unreachable via the IPsec tunnel because

  • they are somewhere else in your LAN than in 192.168.0.0/24, or
  • because the Fortigate filters DNS requests to any servers except the ones they’ve told you, or
  • because the DNS servers you’ve configured do not accept queries from the address to which the Fortigate NATs you (if it does).
  • because the server name is only registered in the DNS of thr Fortigate and public DNSes don’t know about its existence, and the Fortigate does not redirect DNS requests to its own servers

So all in all, describe better the situation to get a more targeted advice. I know silence is golden but not when you need support.

Hi Sindy,

I am able to ping the webserver domain name and it translated the domain to the IP address.
The dns server settings are auto giving to my via PPPoE on the mikrotik and I have remote requests on with the router IP 192.168.0.1 added to the dns list.
If I turn off PPPoE “Use Peer DNS” I can input my own, which I have done and tried google’s DNS 8.8.8.8, 8.8.8.4.4
I also tried removing DNS servers from dhcp handouts on the router and adding DNS straight onto the NIC on my PC.
Once IPSEC is disabled, I can browse the internet like normal but when enabled I cannot.

The admin said that they don’t specify DNS as the webserver address can be resolved by any DNS server.
I can see traffic going over the tunnel when I ping the webserver.
The admin also said that everything looks okay from this end, he can see successful connections to the web server and data passing.
So that leaves the problem at my end

So to recap:

  • With tunnel down, you can access web pages by name and ping the servers by name, except the server for which you needed the IPsec, yes/no?
  • With tunnel up, you can access web pages and ping the servers by address, including the server for which you needed the IPsec, yes/no?
  • With tunnel up:
  • can you ping servers in the internet by name (chose servers you haven’t visited today so that DNS cache doesn’t affect the results)?
    • can you ping that server of interest by name?

And also explain the uplink. You mention PPPoE on your own 'Tik and a router at 192.168.0.1, so you have two uplinks? Normally the ADSL routers either work as routers so you cannot run pppoe client on the 'Tik, or they work as bridges so you run the pppoe but in such case the DNS on the router cannot work as it cannot see the internet, forwarding the PPPoE to you.

So to recap:
With tunnel down, you can access web pages by name and ping the servers by name, except the server for which you needed the IPsec, yes
With tunnel up, you can access web pages and ping the servers by address, including the server for which you needed the IPsec, yes/no? no, I cannot access any websites only the IP of webserver is all.

With tunnel up:
can you ping servers in the internet by name (chose servers you haven’t visited today so that DNS cache doesn’t affect the results)? No
can you ping that server of interest by name? No, I can ping webserver by IP

I have a Mikrotik SXT CPE,
Wlan wireless station mode to ISP Sector AP
PPPoE runs on the Wlan and the ether1 is connect into my PC, DHCP runs on ether1 192.168.0.0/24
Wlan and ether1 are not bridged

Well, could it be that I am missing the key information that the tunnel is only there to access that particular server b.b.b.b, and it actually does not deliver to the destination any other traffic than that for the web server? Because the policy in your first post suggested that this VPN should take your complete internet traffic, but maybe it is the mistake which has only spawned a chain of misunderstanding?

I have an IP address that is for the VPN use only and not to browse the internet.
The IPSEC VPN is used to access the remote webserver login portal page securely, not to browse the internet under the VPN.
But when I use the IP of the webserver it will show that I can reach webserver and I can ping it also from PC and Tik device, but it wont show the login page.

It’s not until I use your rule /ip ipsec policy add place-before=0 action=none src-address=0.0.0.0/0 dst-address=192.168.0.0/24 place-before=0
then I can reach the webserver via the IP address, when I disable above rule I cannot access the webserver via the IP, so that was a step in the right direction.

IPSEC Configuration
VPN Type Route Based
VPN selectors should be 0.0.0.0/0.0.0.0
It is recommend that the client environment is NATed to public IP addressing.

Well, the problem is that “VPN selectors 0.0.0.0/0-0.0.0.0/0”, which is another name for what Mikrotik calls ipsec policy, mean to send everything through the tunnel. And while it was easy to cut away the local LAN from that, it will not be so easy to cut everything except the IP of the web server (b.b.b.b).

So first try to change the policy from src-address=0.0.0.0/0 dst-address=0.0.0.0/0 to src-address=0.0.0.0/0 dst-address=b.b.b.b/32; if the tunnel establishes, we’re good, if it doesn’t, it will require some complex action=none policies before this one.

IPSEC Gateway a.a.a.a
Webserver b.b.b.b

/ip ipsec policy print
Flags: T - template, X - disabled, D - dynamic, I - invalid, A - active,

    • default
      0 ;;; VPN
      src-address=0.0.0.0/0 src-port=any dst-address=b.b.b.b
      dst-port=any protocol=all action=none

1 A ;;; VPN
src-address=0.0.0.0/0 src-port=any dst-address=0.0.0.0/0 dst-port=any
protocol=all action=encrypt level=require ipsec-protocols=esp tunnel=yes
sa-src-address=My-Public-IP sa-dst-address=a.a.a.a
proposal=default ph2-count=1


The tunnel will establish but I cannot reach the webportal via domain or IP with the changes,

Thank you for your help Sindy

What you’ve done is not what I had in mind.
The policy with action=none should have remained unchanged (i.e. with dst-address=192.168.0.0/24) for the moment.
The policy with action=encrypt should have dst-address=b.b.b.b instead of dst-address=0.0.0.0/0.

So the result should be this:

_/ip ipsec policy print
Flags: T - template, X - disabled, D - dynamic, I - invalid, A - active,

    • default
      0 ;;; VPN
      src-address=0.0.0.0/0 src-port=any dst-address=192.168.0.0/24
      dst-port=any protocol=all action=none

      1 A ;;; VPN
      src-address=0.0.0.0/0 src-port=any dst-address=b.b.b.b/32 dst-port=any
      protocol=all action=encrypt level=require ipsec-protocols=esp tunnel=yes
      sa-src-address=My-Public-IP sa-dst-address=a.a.a.a
      proposal=default ph2-count=1_

But as said - the peer may not accept the connection because it gets the information about the policy we use towards it, so if it only accepts connections with policy’s dst-address=0.0.0.0/0, we have an issue which needs to be worked around. On the other hand, if the peer accepts it and it works, the policy with action=none will become redundant and it will be possible to remove it.

/ip ipsec policy print
Flags: T - template, X - disabled, D - dynamic, I - invalid, A - active,

    • default
      0 ;;; VPN
      src-address=0.0.0.0/0 src-port=any dst-address=192.168.0.0/24
      dst-port=any protocol=all action=none

1 A ;;; VPN
src-address=0.0.0.0/0 src-port=any dst-address=b.b.b.b/32 dst-port=any
protocol=all action=encrypt level=require ipsec-protocols=esp tunnel=yes
sa-src-address=My-Public-IP sa-dst-address=a.a.a.a
proposal=default ph2-count=1


I adjusted configuration to above, the connection wont establish with the new changes. Is there any way to troubleshoot what is happening at my side so I can submit results here or is it all trial and error?

It is what I have anticipated. The Fortigate administrator expects that every device in the world behaves like his Fortigate, so he does not even dream that forcing people into use of a policy which matches on all traffic can cause trouble on the clients' side.
To work this around, you will need a pile of action=none policies which will match on packets which should not get to his network, so that only what will get through all those policies unmatched would finally hit that 0.0.0.0/0->0.0.0.0/0 policy and get to him. To make it simpler, I'll show you the method on the first two bytes of the IP address. I hope you are familiar with the conversions between binary and decimal notation and the IP mask construction principle.

So let's say the first two bytes of the b.b.b.b are 217.125. This, in binary, is 1101 1001 0111 1101‬. So we have to go bit by bit and create all the prefixes of different lengths from 1 to 32 which match this value in all their bits except the last one:
1101 1001 ‭0111 1101‬

0... .... .... .... => 0.0.0.0/1
10.. .... .... .... => 128.0.0.0/2
111. .... .... .... => 224.0.0.0/3
1100 .... .... .... => 192.0.0.0/4
1101 0... .... .... => 208.0.0.0/5
1101 11.. .... .... => 220.0.0.0/6
1101 101. .... .... => 218.0.0.0/7
1101 1000 .... .... => 216.0.0.0/8
1101 1001 1... .... => 217.128.0.0/9
1101 1001 00.. .... => 217.0.0.0/10
1101 1001 010. .... => 217.64.0.0/11
1101 1001 0110 .... => 217.96.0.0/12
1101 1001 0111 0... => 217.112.0.0/13
1101 1001 0111 10.. => 217.120.0.0/14
1101 1001 0111 111. => 217.126.0.0/15
1101 1001 0111 1100 => 217.124.0.0/16
So for the actual address b.b.b.b, you have to calculate all the 32 prefixes of non-matching subnet the way above, and use each of them as dst-address of an /ip ipsec policy action=none placed above the single policy with action=encrypt dst-address=0.0.0.0 required by the Fortigate. The good point is that if you go this way, you can remove the previously added policy with action=none as one of those will substitute it.

But there may be a much easier way which you should try first. The guy asks you to send him packets with a public address as a source one, and the reason is that he needs to be sure that two clients won't send him packets from the same address, so that the Fortigate knew where to route the responses. But it does not necessarily need to be the same public address from which you establish the tunnel.

So do the following - keep the configuration with just the two policies we had yesterday, action=none src-address=0.0.0.0/0 dst-address=192.168.0.0/24 and action=encrypt src-address=0.0.0.0/0 dst-address=0.0.0.0/0, and put above the action=encypt one yet another action=none one with src-address=your.wan.ip.address dst-address=0.0.0.0/0

This will make the tunnel establish successfully but will prevent anything from being sent through it, because whatever you send outside your LAN is first src-nated to your WAN public address.

Now take some public IP address which you control and are sure that it won't ever connect to that Fortigate's VPN, say, m.m.m.m, and add the following rule above the currrent action=masquerade or action=src-nat rule you use in /ip firewall nat chain=srcnat:

/ip firewall nat add chain=srcnat action=src-nat dst-address=b.b.b.b to-addresses=m.m.m.m

So the source address of packets you sent to b.b.b.b will be translated to m.m.m.m, so the second policy with action=none will ignore them, and the action=encrypt policy will match them and send them to the Fortigate.

IPSEC Gateway a.a.a.a
Webserver b.b.b.b

0 ;;; VPN
src-address=0.0.0.0/0 src-port=any dst-address=192.168.0.0/24
dst-port=any protocol=all action=none

1 ;;; VPN
src-address=My-Public-IP/32 src-port=any dst-address=0.0.0.0/0
dst-port=any protocol=all action=none

2 A ;;; VPN
src-address=0.0.0.0/0 src-port=any dst-address=0.0.0.0/0 dst-port=any
protocol=all action=encrypt level=require ipsec-protocols=esp tunnel=yes
sa-src-address=My-Public-IP sa-dst-address=a.a.a.a
proposal=default ph2-count=1


I added a second PPPoE with a new public IP, So there is two PPPoE running at the same time with two different public addresses, is this correct?

Firewall Rule
/ip firewall nat add chain=srcnat action=src-nat dst-address=b.b.b.b to-addresses=New-Public-IP

Results;
Tunnel will establish, but I cannot reach the webserver via domain address or IP address of webserver.

If I disable the second PPPoE and the added new firewall nat rule.
I am able to browse the internet like normal with the new policy rule active and the tunnel is established.

Thanks for your time with all this.

I don’t know whether you have static addresses or dynamic on the PPPoE, but from your description it seems they are dynamic which makes the setup quite unstable (as soon as the addresses change, it will stop working until you adjust the rules to the addresses), something which the one with 32 exception policies is not sensitive about.

In any case, change the settings of the /interface pppoe-client in such a way that the one with your normal public address is allowed to add default gateway and the other one is not. So even if the second one is up, your packets will always go out via the first one. The public address of the first pppoe (which is allowed to become the default route’s gateway iterface) must be the one in the policy with action=none, the public address of the second pppoe (which is not allowed to become the default route’s gateway interface) must be in the rule I gave you. Just to check, please give me the output of /interface pppoe-client export hide-sensitive and /ip firewall nat export, replacing the IP addresses there of course.

Default Route
0.0.0.0/0 Gatway pppoe-out1

/interface pppoe-client
add disabled=no interface=wlan2 keepalive-timeout=60 name=pppoe-out1 use-peer-dns=yes user=*******1
add disabled=no interface=wlan2 name=pppoe-out2 user=*******2

/ip firewall nat
add action=src-nat chain=srcnat comment=“Public-Ip-2 to Webserver IP” dst-address=b.b.b.b to-addresses=m.m.m.m
add action=src-nat chain=srcnat comment=“Public-Ip-1 Src-Nat” src-address=192.168.0.0/24 to-addresses=z.z.z.z

Okay. And with this setup, you can get to the internet normally, the IPsec tunnel is up, but you cannot connect to the server b.b.b.b neither by IP nor by name? And when you try, you can see the /ip ipsec installed-sa from your z.z.z.z to their a.a.a.a to count packets and bytes but the one for the opposite direction doesn’t?