######################################################################## # VoIP Mikrotik script : symetric NAT and firewall filter rules # # Author : G. HUSSON, Liberasys, 201904, contact_web _@_ liberasys.com # # License : EUPL v1.2 - https://opensource.org/licenses/EUPL-1.2 # # Prerequisits : having preestablished firewall rules and masquerading # # HOWTO : # # - set variables corresponding to your installation # # - run the script # # - move the firewall rules in firewall filter rules where it # # shoud be # ######################################################################## # Set variables (change them !!!!) :global internalIp "192.168.0.10"; :global internalInterface "bridge-internal"; :global externalIp "1.2.3.4"; :global externalInterface "bridge-internet"; :global voipHttpsPort 443; :global voipHttpPort 80; :global voipSIPPort 5060; :global voipSIPsPort ($voipSIPPort + 1); :global voipTunnelPort 5090; :global voipMediaPort "9000-10999"; :global initialNatRulesPosition 0; # Clean previously defined rules /ip firewall nat remove [ find comment ~ "(#VOIPscript)" ] /ip firewall filter remove [ find comment ~ "(#VOIPscript)" ] # Disable SIP ALG /ip firewall service-port disable sip # Set NAT rules (they have to be before any masquerading rule) /ip firewall nat add action=dst-nat \ chain=dstnat \ in-interface=$externalInterface \ dst-address=$externalIp \ protocol=tcp \ dst-port="$voipHttpsPort,$voipHttpPort,$voipSIPPort,$voipSIPsPort,$voipTunnelPort" \ to-addresses=$internalIp \ log=yes \ log-prefix=voip-in \ place-before=$initialNatRulesPosition \ comment="VoIP TCP - IN (#VOIPscript)" /ip firewall nat add action=src-nat \ chain=srcnat \ src-address=$internalIp \ out-interface=$externalInterface \ protocol=tcp \ src-port="$voipHttpsPort,$voipHttpPort,$voipSIPPort,$voipSIPsPort,$voipTunnelPort" \ to-addresses=$externalIp \ log=yes \ log-prefix=voip-out \ place-before=$initialNatRulesPosition \ comment="VoIP TCP - OUT, symetric NAT (#VOIPscript)" /ip firewall nat add action=dst-nat \ chain=dstnat \ in-interface=$externalInterface \ dst-address=$externalIp \ protocol=udp \ dst-port="$voipSIPPort,$voipSIPsPort,$voipTunnelPort,$voipMediaPort" \ to-addresses=$internalIp \ log=yes \ log-prefix=voip-in \ place-before=$initialNatRulesPosition \ comment="VoIP UDP - IN (#VOIPscript)" /ip firewall nat add action=src-nat \ chain=srcnat \ src-address=$internalIp \ out-interface=$externalInterface \ protocol=udp \ src-port="$voipSIPPort,$voipSIPsPort,$voipTunnelPort,$voipMediaPort" \ to-addresses=$externalIp \ log=yes \ log-prefix=voip-out \ place-before=$initialNatRulesPosition \ comment="VoIP UDP - OUT, symetric NAT (#VOIPscript)" # Set firewall filter rules /ip firewall filter add action=accept chain=forward \ in-interface=$externalInterface \ out-interface=$internalInterface \ dst-address=$internalIp \ protocol=tcp \ dst-port="$voipHttpsPort,$voipHttpPort,$voipSIPPort,$voipSIPsPort,$voipTunnelPort" \ log=yes \ log-prefix=voip-in \ comment="Internet -> VoIP server - TCP (#VOIPscript)" /ip firewall filter add action=accept chain=forward \ in-interface=$externalInterface \ out-interface=$internalInterface \ dst-address=$internalIp \ protocol=udp \ dst-port="$voipSIPPort,$voipSIPsPort,$voipTunnelPort,$voipMediaPort" \ log=yes \ log-prefix=voip-in \ comment="Internet -> VoIP server - UDP (#VOIPscript)" # Add drop rule for IP that have been added to "blacklist-sip" # address list /ip firewall filter add action=drop \ chain=forward \ src-address-list=blacklist-sip \ comment="blacklist-sip DROP (#VOIPscript)" \ # Add drop rule for IP that have been added to "blacklist-3cxtunnel" # address list /ip firewall filter add action=drop \ chain=forward \ src-address-list=blacklist-3cxtunnel \ comment="blacklist-3cxtunnel DROP (#VOIPscript)" # Add an IP to "sip-blacklist" address list, based on connection # number (max 10 SIP sessions per IP) and packet rate (max 100 packets # in 1mn) - adapt it to your field use. /ip firewall filter add action=add-src-to-address-list \ chain=forward \ protocol=udp \ dst-port=5060 \ connection-limit=10,32 \ connection-state=invalid,new,untracked \ limit=100/1m,0:packet \ address-list=blacklist-sip \ address-list-timeout=3h \ log=yes \ log-prefix=hacker-sip \ comment="Add SIP hacker IP to blacklist-sip (#VOIPscript)" # Add an IP to "blacklist-3cxtunnel" address list, based on connection # rate (max 4 tunnels per IP) - adapt it to your field use. /ip firewall filter add action=add-src-to-address-list \ chain=forward \ protocol=udp \ dst-port=5060 \ connection-limit=4,32 \ connection-state=invalid,new,untracked \ address-list=blacklist-3cxtunnel \ address-list-timeout=3h \ log=yes \ log-prefix=hacker-3cxtnl \ comment="Add SIP hacker IP to iblacklist-3cxtunnel (#VOIPscript)" # Reference documentation for connection-limit and limit: # https://wiki.mikrotik.com/wiki/Manual:IP/Firewall/Filter # connection-limit: Matches connections per address or address block # up to and including given value. Should be used together with # connection-state=new and/or with tcp-flags=syn because matcher is # very resource intensive. # limit (integer,time,integer; Default: ): Matches packets up to a # limited rate (packet rate or bit rate). Rule using this matcher will # match until this limit is reached. Parameters are written in # following format: count[/time],burst:mode. # * count: packet or bit count per time interval to match # * time: specifies the time interval in which the packet or bit count # cannot be exceeded (optional, 1s will be used if not specified) # * burst: initial number of packets or bits to match: this number # gets recharged every 10ms so burst should be at least 1/100 # of rate per second # * mode: packet or bit mode # Clean variables :set internalIp; :set internalInterface; :set externalIp; :set externalInterface; :set voipHttpsPort; :set voipHttpPort; :set voipSIPPort; :set voipSIPsPort; :set voipTunnelPort; :set voipMediaPort; :set initialNatRulesPosition;