Logging Firewall Traffic on a Synology NAS

by 15th April 2022Security, Synology, Technological Thoughts

Code Updated!

Thank you to everyone who commented, and provided me with their iptables. I finally isolated the problem by starting up a virtual DSM and running it from scratch.

The firewall.conf file written in the first part of the code was not being loaded by syslog before the firewall rules were then written. Because I had carried out that step when writing the script, it always worked for me!

I’ve added an additional command into the code that restarts syslog before adding the firewall rules, which resolves the problem.

Let me know in the comments if there any more problems, or even better, if it works for you!

I’ve seen a lot of queries on the internet about logging firewall traffic on a Synology server, because, somewhat surprisingly, it’s not something that Synology have implemented in their Log Center (sic) or feel is important enough, despite providing the functionality to easily create firewall rules in the Control Panel.

Underneath it all, Synology uses IPTables to implement firewall rules. It’s not easy or straightforward to manage these on the command line, which is why, thankfully, Synology have provided a nice GUI to allow you to add and change rules on the fly. Confusingly, they don’t provide a method to audit or troubleshoot why a rule might not be working.

Getting Firewall Logs into Synology Log Center

There is a solution to this, and one that doesn’t require you to delve into the innards of the server (although you can if you want!). The configuration is designed to withstand reboots (since IPTables revert to their default configuration whenever the server reboots) and to be managed from within Synology DSM. It also doesn’t mess around with any Synology defaults or specific configurations, so in theory, should always work.

Creating a Task to Enable Firewall Logging

First off, log into your Synology DSM and open the Control Panel, and under the Services section, select “Task Scheduler”.

In the Task Scheduler screen, select the Create button and then the “User-defined script” under the “Triggered Task” menu option, since we are going to set something up that will always run on boot-up.

Enter a name for your task, so you know what it’s for and make sure the “User” field is set to “root” and the “Event” field to “Boot-up”.

Click on the Task Settings tab. Then in the “User-defined script” field, enter the following code:

#!/bin/bash
conf='/usr/local/etc/syslog-ng/patterndb.d/Firewall.conf'
echo 'destination d_iptables {' > $conf
echo 'syslog("127.0.0.1" port(514) transport("udp"));' >> $conf
echo '};' >> $conf
echo 'filter f_iptables { match("--Firewall--"); };' >> $conf
echo 'log { source(src); filter(f_iptables); destination(d_iptables); };' >> $conf
systemctl restart syslog-ng
iptables -N LOGGING
iptables -I INPUT 1 -j LOGGING
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix '--Firewall--' --log-level 6

Click on the OK button. The task is now set up to enable firewall logging whenever your Synology is rebooted.

Bear in mind that the code hasn’t been run yet, so the logging hasn’t been configured. You can reboot your server to set it up, but we’re going to stick with doing everything through Synology DSM.

Highlight your newly created task in the Task Scheduler and click the Run button at the top of the screen. Now your server is configured to send firewall logs to Synology Log Center.

Limiting the Logging to External Traffic

If you want to limit the logging to only monitor external traffic, then you can insert the following line before line 10:

iptables -A LOGGING -s 192.168.1.0/24 -j RETURN

Replace “192.168.1.0/24” in the line with your local network range. The /24 at the end is known as CIDR (Classless Inter-Domain Routing), and means that it will not log any traffic coming in from 192.168.1.0 to 192.168.1.255.

The full script is then:

#!/bin/bash
conf='/usr/local/etc/syslog-ng/patterndb.d/Firewall.conf'
echo 'destination d_iptables {' > $conf
echo 'syslog("127.0.0.1" port(514) transport("udp"));' >> $conf
echo '};' >> $conf
echo 'filter f_iptables { match("--Firewall--"); };' >> $conf
echo 'log { source(src); filter(f_iptables); destination(d_iptables); };' >> $conf
systemctl restart syslog-ng
iptables -N LOGGING
iptables -I INPUT 1 -j LOGGING
iptables -A LOGGING -s 192.168.1.0/24 -j RETURN
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix '--Firewall--' --log-level 6

Enabling Logging in Synology Log Center

We’ve set up Synology so that firewall logging is configured and will survive a reboot of your server, but it’s still not logging. Firstly, we haven’t configured Log Center to receive the data, and we haven’t told it to read the newly created configuration file.

Open up Log Center in Synology DSM and click on the Log Receiving tab, then click on the Create button at the top.

Type in a name for your rule so you know what it relates to and make sure you have selected the IETF Log format. By default, the transfer protocol should be “UDP” and the Port should be “514”.

Finally, click on the OK button and make sure your rule is enabled.

Viewing the Firewall Logs

You’re done! Your Synology should now be sending (and receiving) the firewall logs in Log Center. To check that, go to the Logs tab. By default, you will see all of the general logs for the server.

We’ve configured the Synology to send the firewall logs to the server rather than trying to hack around with the Synology server itself, so click in the drop-down where it says “Local”. The name of your Server should now be displayed underneath (in my case, “Gaia”).

You should now be able to see all of your incoming firewall logs, in their raw format in Log Center.

A Word of Explanation

If you’re interested in what the code does, I’ve broken it down line by line here.

#!/bin/bash

Tells Synology to use the Bash shell to run the commands.

conf='/usr/local/etc/syslog-ng/patterndb.d/Firewall.conf'

Sets a variable to define where we are going to create the Firewall logging configuration.

echo 'destination d_iptables {' > $conf

Writes the first line defining where the firewall logs should go to the Firewall logging configuration.

echo 'syslog("127.0.0.1" port(514) transport("udp"));' >> $conf

Writes the second line telling syslog to send all logs to the local server using UDP over port 514.

echo '};' >> $conf

Writes the third line closing the destination details.

echo 'filter f_iptables { match("--Firewall--"); };' >> $conf

Writes a line to look for logs that include –Firewall– in the log itself.

echo 'log { source(src); filter(f_iptables); destination(d_iptables); };' >> $conf

Writes the command that tells syslog where to get the logs from, what to filter for and where to send it.

systemctl restart syslog-ng

Restarts the syslog so that the firewall rules can write to Log.

iptables -N LOGGING

Creates a LOGGING chain in the iptables configuration.

iptables -I INPUT 1 -j LOGGING

Makes sure that any traffic going through the IP Table firewall rules must also go to the LOGGING chain.

iptables -A LOGGING -s 192.168.1.0/24 -j RETURN

If the source IP address is in the local network (192.168.1.0 to 192.168.1.255) return the traffic and don’t process the next rule.

iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix '--Firewall--' --log-level 6

Tell iptables to make sure that any firewall log is prefixed with –Firewall– (so we can filter on that), and to suppress duplicate logs so we don’t get a flurry of the same information in the log file. Finally, it sets the level of information to 6, which is “INFO”. If you want to only display “WARNING” logging, then the level is 4, “EMERGENCY” is 0 and the most verbose, “DEBUG”, is 7.

Matthew Cunliffe

Matthew Cunliffe

Author

Matthew is an IT specialist with more than 23 years experience in software development and project management. He has a wide range of interests, including international political theory; playing guitar; music; hiking, kayaking, and bouldering; and data privacy and ethics in IT.

21 Comments

  1. Baris

    I get the same Error Messages described by other comments.
    It seems like the new DSM Version doesn’t have the LOG Target active, wich seems a bit strange to me as an lsmod | grep LOG shows xt_LOG package installed.
    Do we also need to activate the module if yes how?
    Does anyone has an advice as this feature would make the firewall 100x better 😀

    Reply
    • Matthew Cunliffe

      Hi Baris,
      I’m hoping that the change I made to the code on line 8
      systemctl restart syslog-ng
      resolves this issue as it will then enable the LOG target into the Log Center in DSM.

      Reply
      • Baris

        Hi Matthew,

        thanks to your reply sadly that didnt worked out :/
        My DSM Version is DSM 7.1-42661 Update 4
        and Kernel Version 4.4.180+.

        The Output of lsmod | grep LOG

        xt_LOG 1487 0
        x_tables 16976 22 ip6table_filter,xt_ipvs,xt_iprange,xt_mark,xt_recent,ip_tables,xt_tcpudp,ipt_MASQUERADE,xt_geoip,xt_limit,xt_state,xt_conntrack,xt_LOG,xt_mac,xt_nat,xt_multiport,iptable_filter,xt_TCPMSS,xt_REDIRECT,iptable_mangle,ip6_tables,xt_addrtype

        so xt_LOG seems to be available.

        Reply
      • Baris

        One more thing i like to add.

        Matthew, could you also provide the output of your /proc/net/netfilter/nf_log ?

        Mine is looking like this:

        0 NONE ()
        1 NONE ()
        2 NONE ()
        3 NONE ()
        4 NONE ()
        5 NONE ()
        6 NONE ()
        7 NONE ()
        8 NONE ()
        9 NONE ()
        10 NONE ()
        11 NONE ()
        12 NONE ()

        seeing this no nf_log modules are loaded espacially for 2 (IPV4)
        however trying to modprope nf_log_ipv4 or trying to echo xt_log to 2 doesnt work.

        I think the new kernel of the synology linux distribution don’t have nf_log_ipv4 available.

        Reply
        • Matthew Cunliffe

          Hi Baris,
          I am on the same DSM release (7.1-42661 Update 4), but my kernel is a bit (lot!) older: 3.10.108. xt_LOG is available and my nf_log shows the following that differ from yours:

          2 ipt_LOG (ipt_LOG)
          10 ip6t_LOG (ip6t_LOG)

          I think the issue is that after kernel 3.17, logging switches to NF from IPT.

          If you ran the following command, does this enable the logging for you?

          nft add rule x y log flags ip options

          It would be really good if I can put together a script that identifies which kernel is being used and applies the appropriate commands so it’s a universal script! Any help with that would be much appreciated.

          Reply
          • Baris Keskin

            Sure i do the best i can to get this working =)

            okay so if i run your provided command it returns nft: command not found.

            it is a really strange behavior, i also checked

            cat /usr/syno/etc.defaults/iptables_modules_list

            this file provides the loaded modules while booting. xt_log.ko ist part of the KERNEL_MODULES_CORE

            i will provide the output of my startup file:

            KERNEL_MODULES_NAT=”nf_conntrack.ko nf_defrag_ipv4.ko nf_conntrack_ipv4.ko nf_nat.ko nf_nat_redirect.ko nf_nat_ipv4.ko iptable_nat.ko xt_nat.ko nf_nat_masquerade_ipv4.ko xt_REDIRECT.ko ipt_MASQUERADE.ko”
            PPTP_MODULES=”arc4.ko ppp_mppe.ko bsd_comp.ko zlib_inflate.ko zlib_deflate.ko ppp_deflate.ko gre.ko pptp.ko”
            GEOIP_MODULES=”xt_geoip.ko”
            KERNEL_MODULES_COMMON=”x_tables.ko nf_conntrack.ko xt_multiport.ko xt_tcpudp.ko xt_state.ko xt_limit.ko xt_iprange.ko xt_recent.ko”
            PPPOE_MODULES=”pppoe.ko n_hdlc.ko ppp_synctty.ko”
            OPENVPN_MODULES=”tun.ko”
            KERNEL_MODULES_CORE=”x_tables.ko ip_tables.ko iptable_filter.ko nf_conntrack.ko nf_defrag_ipv4.ko nf_conntrack_ipv4.ko xt_LOG.ko”
            TC_6_MODULES=”ip6table_mangle.ko”
            IPV6_MODULES=”x_tables.ko nf_conntrack.ko ip6_tables.ko ip6table_filter.ko nf_defrag_ipv6.ko nf_conntrack_ipv6.ko”
            L2TP_MODULES=”echainiv.ko arc4.ko ppp_mppe.ko bsd_comp.ko zlib_inflate.ko zlib_deflate.ko ppp_deflate.ko udp_tunnel.ko ip6_udp_tunnel.ko l2tp_core.ko l2tp_ppp.ko hmac.ko xfrm_algo.ko xfrm_user.ko af_key.ko xfrm_ipcomp.ko ah4.ko ah6.ko esp4.ko esp6.ko tunnel4.ko tunnel6.ko xfrm4_tunnel.ko xfrm6_tunnel.ko ipcomp.ko ipcomp6.ko authenc.ko authencesn.ko deflate.ko xfrm4_mode_beet.ko xfrm6_mode_beet.ko xfrm4_mode_tunnel.ko xfrm6_mode_tunnel.ko xfrm4_mode_transport.ko xfrm6_mode_transport.ko xt_policy.ko”
            TC_MODULES=”iptable_mangle.ko cls_fw.ko cls_u32.ko sch_htb.ko sch_sfq.ko xt_mark.ko”
            PPP_MODULES=”slhc.ko ppp_generic.ko ppp_async.ko pppox.ko x_tables.ko ip_tables.ko iptable_mangle.ko xt_tcpudp.ko xt_TCPMSS.ko”

  2. jrowe

    Hi,

    First thing, thanks for your work.

    I have a Synology router RT2600ac (SRM 1.2.5-8227 Update 5). Does your trick work on it, or just on with NAS (DSM)?

    Thanks by advance.

    Reply
    • Matthew Cunliffe

      Hi Jonathan,
      I don’t have a router I can test on, but looking at the specs for the SRM (Synology Router Manager), it seems to be variant of the DSM. It has the Log Center, and I would be surprised if it doesn’t use IPTables.

      The only thing I would be unsure of is whether the file system is the same.

      If you are able to run the following command from a shell on the router and it returns a file listing, I would say it is likely to work:
      ls /usr/local/etc/syslog-ng/patterndb.d/

      Reply
    • Arsach

      Hi,

      Same issue here, I got the “iptables: No chain/target/match by that name.” when adding the last rule to LOGGING chain.

      Quick remark : you might want to fix the full script displayed in your tutorial, in row 4 the echo command is not correctly redirected to conf file

      Reply
      • Matthew Cunliffe

        Many thanks, I have fixed the script. I’ll look at working up an alternative to those with later kernels using NF instead of IPT. Apologies for the delay!

        Reply
  3. Matthew Cunliffe

    Thanks to all of you for commenting and helping me to identify the issue. I hope this script now works for all of you and the firewall traffic logs correctly in Log Center!

    Reply
  4. Alex

    Hello Mat,
    Thanks to spend some time on this, this “missing” firewall log functionality is really a concern for me and I hope you will find some workaround to make your script work for everyone.
    Same issue on my Synology, here is the IP table :

    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    DOS_PROTECT all — anywhere anywhere
    INPUT_FIREWALL all — anywhere anywhere
    DEFAULT_INPUT all — anywhere anywhere

    Chain FORWARD (policy ACCEPT)
    target prot opt source destination
    FORWARD_FIREWALL all — anywhere anywhere

    Chain OUTPUT (policy ACCEPT)
    target prot opt source destination

    Chain DEFAULT_INPUT (1 references)
    target prot opt source destination
    LOGGING all — anywhere anywhere

    Chain DOS_PROTECT (1 references)
    target prot opt source destination
    RETURN icmp — anywhere anywhere icmp echo-request limit: avg 1000/sec burst 5
    DROP icmp — anywhere anywhere icmp echo-request
    RETURN tcp — anywhere anywhere tcp flags:FIN,SYN,RST,ACK/RST limit: avg 1/sec burst 5
    DROP tcp — anywhere anywhere tcp flags:FIN,SYN,RST,ACK/RST
    RETURN tcp — anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN limit: avg 10000/sec burst 100
    DROP tcp — anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN

    Chain FORWARD_FIREWALL (1 references)
    target prot opt source destination
    ACCEPT all — anywhere anywhere
    ACCEPT all — anywhere anywhere state RELATED,ESTABLISHED
    RETURN tcp — anywhere anywhere tcp dpt:ssh
    RETURN udp — anywhere anywhere multiport sports netbios-dgm,netbios-ns,19997
    RETURN tcp — anywhere anywhere multiport dports 6011:6030,16881,rtsp,6690
    RETURN udp — anywhere anywhere multiport dports ntp,x11-1:6010,53535,6881,19998,19999
    RETURN tcp — anywhere anywhere multiport dports domain,microsoft-ds,netbios-ssn,netbios-dgm,netbios-ns
    RETURN udp — anywhere anywhere multiport dports domain,microsoft-ds,netbios-ssn,netbios-dgm,netbios-ns
    RETURN all — 10.0.0.0/8 anywhere
    RETURN all — 172.16.0.0/12 anywhere
    RETURN all — 192.168.0.0/16 anywhere
    RETURN tcp — anywhere anywhere -m geoip –source-country FR,GF multiport dports https,2701
    RETURN all — anywhere anywhere source IP range 91.108.4.0-91.108.4.22
    RETURN all — anywhere anywhere source IP range 149.154.160.0-149.154.160.20
    DROP all — anywhere anywhere

    Chain INPUT_FIREWALL (1 references)
    target prot opt source destination
    ACCEPT all — anywhere anywhere
    ACCEPT all — anywhere anywhere state RELATED,ESTABLISHED
    RETURN tcp — anywhere anywhere tcp dpt:ssh
    RETURN udp — anywhere anywhere multiport sports netbios-dgm,netbios-ns,19997
    RETURN tcp — anywhere anywhere multiport dports 6011:6030,16881,rtsp,6690
    RETURN udp — anywhere anywhere multiport dports ntp,x11-1:6010,53535,6881,19998,19999
    RETURN tcp — anywhere anywhere multiport dports domain,microsoft-ds,netbios-ssn,netbios-dgm,netbios-ns
    RETURN udp — anywhere anywhere multiport dports domain,microsoft-ds,netbios-ssn,netbios-dgm,netbios-ns
    RETURN all — 10.0.0.0/8 anywhere
    RETURN all — 172.16.0.0/12 anywhere
    RETURN all — 192.168.0.0/16 anywhere
    RETURN tcp — anywhere anywhere -m geoip –source-country FR,GF multiport dports https,2701
    RETURN all — anywhere anywhere source IP range 91.108.4.0-91.108.4.22
    RETURN all — anywhere anywhere source IP range 149.154.160.0-149.154.160.20
    DROP all — anywhere anywhere

    Chain LOGGING (1 references)
    target prot opt source destination
    RETURN all — 192.168.0.0/24 anywhere

    Reply
  5. Idir

    Hi,

    First of all thks a lot for your work, i was looking for this for so long time…
    UnfortuntelyI have the same problem:
    “iptables: Chain already exists.
    iptables: No chain/target/match by that name.”

    Reply
    • Matthew Cunliffe

      Idir, Thank you for letting me know. I have been looking into this and there must be a difference between the firewall rules base on my server compared to everyone elses!

      To help me fix this would you be able to type “iptables -L” inside a shell console and send me the results via the Contact Us form? I can then check the which rule it is failing on for you!

      Many thanks.

      Reply
      • Matt S

        Hi Matthew,

        Did you ever get to the bottom of this?

        I can get the iptables -L information if required.

        Thanks!

        Reply
        • Matthew Cunliffe

          Matt,

          If you could send me the iptables list that would be extremely helpful! I am unable to replicate the issue on my server definitively, as it is not clear which chain is missing.

          Many thanks.

          Reply
          • Matthew Cunliffe

            As an update, I have been looking into this, but I think I need to spin up a virtual machine and create some test IPtables to validate it. Apologies to all for the delay, and many thanks to Matt S for supplying me with sample IPtables to check!

  6. woila

    Any progress?
    Same problem ? here:
    “iptables: Chain already exists.
    iptables: No chain/target/match by that name.”

    The “iptables: Chain already exists.” error gives some promising hits in search engines. But I’m not experienced enough to try anything. Deleted the task for now.

    Reply
    • Matthew Cunliffe

      Thanks for the update Ivo.

      The first error tells me that it has created the expected chain if you have already run it once (or as it says, the chain name already existed in your firewall rules.)

      I will have a look at the next line. It must be a non-visible error (spaces, or ASCII character type) causing the issue, because running it myself from a text file causes no problems!

      Reply
  7. Daniele

    Not working

    No chain/target/match by that name.

    Referred to the -j LOG chain
    It fails on this command:
    iptables -A LOGGING -m limit –limit 2/min -j LOG –log-prefix ‘–Firewall–‘ –log-level 6

    Reply
    • Matthew Cunliffe

      Daniele, Thank you very much for letting me know. I have been unable to replicate this error directly, but I will do some further investigation to see why it might be failing for you.

      Reply

Submit a Comment

Your email address will not be published.

Share this post