3

I'm rather new to Ubuntu. I'm trying to lock it down to where I have complete access to it from my ip address and everyone else only has access to port 80 and 443.

To better understand it, I put my commands in a script. Plus, it makes it easier to rerun if I screw it up. Needless to say, I've run this quite a few times, without any luck.

I can connect via my ssh port (not the default 22) without issue. I can ping out of the server.

The port I'm using for Portainer, I'll use 9999 for the example, is accessible by everyone, regardless of ip address. I only want port 80 and 443 accessible to the public.

The script I created:

#!/bin/bash

# Flush (-F) existing rules
iptables -F

# Set default policies (-P)
# Accept all input to server
iptables -P INPUT ACCEPT
# Accept all forwarding from server
iptables -P FORWARD ACCEPT
# Accept all output from server
iptables -P OUTPUT ACCEPT

# Allow (-A) incoming traffic on loopback interface
iptables -A INPUT -i lo -j ACCEPT

# Allow all outgoing traffic
iptables -I OUTPUT -o eth0 -d 0.0.0.0/0 -j ACCEPT
# Allow incoming traffic that has been established from an outgoing connection
iptables -I INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow incoming traffic on port 80 (HTTP)
iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT

# Allow incoming traffic on port 443 (HTTPS)
iptables -A INPUT -i eth0 -p tcp --dport 443 -j ACCEPT

# Screw it, let me have full access dammit
iptables -A INPUT -s x.x.x.84 -j ACCEPT

# Drop all other incoming traffic
iptables -A INPUT -j DROP

# Save the rules to persist across reboots
iptables-save > /etc/iptables/rules.v4

# Force persistent rules
sh -c 'iptables-save > /etc/iptables/rules.v4'

These are my firewall rules after I ran the above:

table inet filter {
    chain input {
        type filter hook input priority filter; policy accept;
    }

    chain forward {
        type filter hook forward priority filter; policy accept;
    }

    chain output {
        type filter hook output priority filter; policy accept;
    }
}
table ip filter {
    chain INPUT {
        type filter hook input priority filter; policy accept;
        iifname "eth0" ct state related,established counter packets 51 bytes 4755 accept
        iifname "lo" counter packets 6 bytes 680 accept
        iifname "eth0" meta l4proto tcp tcp dport 80 counter packets 0 bytes 0 accept
        iifname "eth0" meta l4proto tcp tcp dport 443 counter packets 11 bytes 528 accept
        ip saddr xx.xx.xx.84 counter packets 0 bytes 0 accept
        counter packets 35 bytes 1688 drop
    }

    chain FORWARD {
        type filter hook forward priority filter; policy accept;
    }

    chain OUTPUT {
        type filter hook output priority filter; policy accept;
        oifname "eth0" counter packets 41 bytes 3721 accept
    }

    chain ufw-after-forward {
    }

    chain ufw-after-input {
    }

    chain ufw-after-logging-forward {
    }

    chain ufw-after-logging-input {
    }

    chain ufw-after-logging-output {
    }

    chain ufw-after-output {
    }

    chain ufw-before-forward {
    }

    chain ufw-before-input {
    }

    chain ufw-before-logging-forward {
    }

    chain ufw-before-logging-input {
    }

    chain ufw-before-logging-output {
    }

    chain ufw-before-output {
    }

    chain ufw-reject-forward {
    }

    chain ufw-reject-input {
    }

    chain ufw-reject-output {
    }

    chain ufw-track-forward {
    }

    chain ufw-track-input {
    }

    chain ufw-track-output {
    }

    chain DOCKER {
    }

    chain DOCKER-ISOLATION-STAGE-1 {
    }

    chain DOCKER-ISOLATION-STAGE-2 {
    }

    chain DOCKER-USER {
    }

    chain ufw-logging-deny {
    }

    chain ufw-logging-allow {
    }

    chain ufw-skip-to-policy-input {
    }

    chain ufw-skip-to-policy-output {
    }

    chain ufw-skip-to-policy-forward {
    }

    chain ufw-not-local {
    }

    chain ufw-user-input {
    }

    chain ufw-user-output {
    }

    chain ufw-user-forward {
    }

    chain ufw-user-logging-input {
    }

    chain ufw-user-logging-output {
    }

    chain ufw-user-logging-forward {
    }

    chain ufw-user-limit {
    }

    chain ufw-user-limit-accept {
    }
}
table ip6 filter {
    chain INPUT {
        type filter hook input priority filter; policy drop;
        counter packets 185 bytes 18491 jump ufw6-before-logging-input
        counter packets 185 bytes 18491 jump ufw6-before-input
        counter packets 1 bytes 76 jump ufw6-after-input
        counter packets 1 bytes 76 jump ufw6-after-logging-input
        counter packets 1 bytes 76 jump ufw6-reject-input
        counter packets 1 bytes 76 jump ufw6-track-input
    }

    chain FORWARD {
        type filter hook forward priority filter; policy drop;
        counter packets 0 bytes 0 jump ufw6-before-logging-forward
        counter packets 0 bytes 0 jump ufw6-before-forward
        counter packets 0 bytes 0 jump ufw6-after-forward
        counter packets 0 bytes 0 jump ufw6-after-logging-forward
        counter packets 0 bytes 0 jump ufw6-reject-forward
        counter packets 0 bytes 0 jump ufw6-track-forward
    }

    chain OUTPUT {
        type filter hook output priority filter; policy accept;
        counter packets 387 bytes 33586 jump ufw6-before-logging-output
        counter packets 387 bytes 33586 jump ufw6-before-output
        counter packets 190 bytes 19582 jump ufw6-after-output
        counter packets 190 bytes 19582 jump ufw6-after-logging-output
        counter packets 190 bytes 19582 jump ufw6-reject-output
        counter packets 190 bytes 19582 jump ufw6-track-output
    }

    chain ufw6-after-forward {
    }

    chain ufw6-after-input {
        meta l4proto udp udp dport 137 counter packets 0 bytes 0 jump ufw6-skip-to-policy-input
        meta l4proto udp udp dport 138 counter packets 0 bytes 0 jump ufw6-skip-to-policy-input
        meta l4proto tcp tcp dport 139 counter packets 0 bytes 0 jump ufw6-skip-to-policy-input
        meta l4proto tcp tcp dport 445 counter packets 0 bytes 0 jump ufw6-skip-to-policy-input
        meta l4proto udp udp dport 546 counter packets 0 bytes 0 jump ufw6-skip-to-policy-input
        meta l4proto udp udp dport 547 counter packets 0 bytes 0 jump ufw6-skip-to-policy-input
    }

    chain ufw6-after-logging-forward {
        limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW BLOCK] "
    }

    chain ufw6-after-logging-input {
        limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW BLOCK] "
    }

    chain ufw6-after-logging-output {
        limit rate 3/minute burst 10 packets counter packets 129 bytes 11997 log prefix "[UFW ALLOW] "
    }

    chain ufw6-after-output {
    }

    chain ufw6-before-forward {
        rt type 0 counter packets 0 bytes 0 drop
        ct state related,established counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type destination-unreachable counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type packet-too-big counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type time-exceeded counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type parameter-problem counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type echo-request counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type echo-reply counter packets 0 bytes 0 accept
        counter packets 0 bytes 0 jump ufw6-user-forward
    }

    chain ufw6-before-input {
        iifname "lo" counter packets 0 bytes 0 accept
        rt type 0 counter packets 0 bytes 0 drop
        ct state related,established counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type echo-reply counter packets 0 bytes 0 accept
        ct state invalid counter packets 0 bytes 0 jump ufw6-logging-deny
        ct state invalid counter packets 0 bytes 0 drop
        meta l4proto ipv6-icmp icmpv6 type destination-unreachable counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type packet-too-big counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type time-exceeded counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type parameter-problem counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type echo-request counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type nd-router-solicit ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type nd-router-advert ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type nd-neighbor-solicit ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type nd-neighbor-advert ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  ip6 hoplimit 1 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  ip6 hoplimit 1 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  ip6 hoplimit 1 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type  counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type  counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type  counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type  counter packets 0 bytes 0 accept
        meta l4proto udp ip6 saddr fe80::/10 ip6 daddr fe80::/10 udp sport 547 udp dport 546 counter packets 0 bytes 0 accept
        meta l4proto udp ip6 daddr ff02::fb udp dport 5353 counter packets 129 bytes 11997 accept
        meta l4proto udp ip6 daddr ff02::f udp dport 1900 counter packets 0 bytes 0 accept
        counter packets 0 bytes 0 jump ufw6-user-input
    }

    chain ufw6-before-logging-forward {
        ct state new limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW AUDIT] "
    }

    chain ufw6-before-logging-input {
        ct state new limit rate 3/minute burst 10 packets counter packets 129 bytes 11997 log prefix "[UFW AUDIT] "
    }

    chain ufw6-before-logging-output {
        ct state new limit rate 3/minute burst 10 packets counter packets 129 bytes 11997 log prefix "[UFW AUDIT] "
    }

    chain ufw6-before-output {
        oifname "lo" counter packets 0 bytes 0 accept
        rt type 0 counter packets 0 bytes 0 drop
        ct state related,established counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type destination-unreachable counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type packet-too-big counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type time-exceeded counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type parameter-problem counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type echo-request counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type echo-reply counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type nd-router-solicit ip6 hoplimit 255 counter packets 86 bytes 4472 accept
        meta l4proto ipv6-icmp icmpv6 type nd-neighbor-advert ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type nd-neighbor-solicit ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type nd-router-advert ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 73 bytes 7008 accept
        meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  ip6 hoplimit 1 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  ip6 hoplimit 1 counter packets 0 bytes 0 accept
        meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  ip6 hoplimit 1 counter packets 0 bytes 0 accept
        counter packets 129 bytes 11997 jump ufw6-user-output
    }

    chain ufw6-reject-forward {
    }

    chain ufw6-reject-input {
    }

    chain ufw6-reject-output {
    }

    chain ufw6-track-forward {
    }

    chain ufw6-track-input {
    }

    chain ufw6-track-output {
        meta l4proto tcp ct state new counter packets 0 bytes 0 accept
        meta l4proto udp ct state new counter packets 129 bytes 11997 accept
    }

    chain ufw6-logging-deny {
        ct state invalid limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW AUDIT INVALID] "
        limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW BLOCK] "
    }

    chain ufw6-logging-allow {
        limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW ALLOW] "
    }

    chain ufw6-skip-to-policy-input {
        counter packets 0 bytes 0 drop
    }

    chain ufw6-skip-to-policy-output {
        counter packets 0 bytes 0 accept
    }

    chain ufw6-skip-to-policy-forward {
        counter packets 0 bytes 0 drop
    }

    chain ufw6-user-input {
    }

    chain ufw6-user-output {
    }

    chain ufw6-user-forward {
    }

    chain ufw6-user-logging-input {
    }

    chain ufw6-user-logging-output {
    }

    chain ufw6-user-logging-forward {
    }

    chain ufw6-user-limit {
        limit rate 3/minute counter packets 0 bytes 0 log prefix "[UFW LIMIT BLOCK] "
        counter packets 0 bytes 0 reject
    }

    chain ufw6-user-limit-accept {
        counter packets 0 bytes 0 accept
    }
}
table ip nat {
    chain DOCKER {
        iifname "docker0" counter packets 0 bytes 0 return
        iifname != "docker0" meta l4proto tcp tcp dport 9443 counter packets 717 bytes 37060 dnat to 172.17.0.2:9443
        iifname != "docker0" meta l4proto tcp tcp dport 8000 counter packets 134 bytes 6120 dnat to 172.17.0.2:8000
    }

    chain POSTROUTING {
        type nat hook postrouting priority srcnat; policy accept;
        oifname != "docker0" ip saddr 172.17.0.0/16 counter packets 18 bytes 1282 masquerade 
        meta l4proto tcp ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 9443 counter packets 0 bytes 0 masquerade 
        meta l4proto tcp ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 8000 counter packets 0 bytes 0 masquerade 
    }

    chain PREROUTING {
        type nat hook prerouting priority dstnat; policy accept;
        fib daddr type local counter packets 100762 bytes 4952330 jump DOCKER
    }

    chain OUTPUT {
        type nat hook output priority -100; policy accept;
        ip daddr != 127.0.0.0/8 fib daddr type local counter packets 0 bytes 0 jump DOCKER
    }
}

I'm going back and forth. I either completely lock myself out of port 9999 or I give everyone full access. Something isn't clicking in my head for this to make sense and I've spent hours on iptables trying to get it to work with Docker and Portainer.

Any assistance would be greatly appreciated!

2
  • 1
    Not an answer to your question, but just out of curiosity... why don't you use ufw ? it's much easier to achieve what you want.
    – pLumo
    Commented Jan 9 at 22:36
  • @pLumo From my understanding, Docker uses iptables. I'm still learning but when I tried to use ufw, it wasn't working with opening up the correct ports for Docker.
    – ErocM
    Commented Jan 19 at 15:24

3 Answers 3

0

I'll try to help. Which cloud is your VM on? I think you need to ensure the VM is getting the correct source IP. If you have a gateway/firewall/proxy in front, it may not be correctly forwarding the source IP. You also need to ensure that your source IP is correct by accessing ifconfig.me from your browser. Regarding iptables, I can't help much, but I would say that if I were in your place, I would use a cloud like Azure, Google Cloud, Oracle, to only release ports 80 and 443, and I would do SSH access from the cloud shell, as it is more secure than direct SSH on port 22, and would put 2FA on the cloud account.

1
  • "Ifconfig .me" (space to prevent linking) is a new one to me, note that if that were a new domain registered for you then the person has almost certainly compromised your server...
    – pbhj
    Commented Jan 15 at 21:04
0

To allow incoming connections for a certain protocol on a certain port from a certain IP and deny incoming connections from other IPs for that protocol and on that port ...

Either

Append to default policy INPUT chain these two rules in this order:

iptables -A INPUT --protocol tcp --dport 9999 --source 10.10.10.10 -j ACCEPT

... to ACCEPT tcp connections to example port 9999 from example source IP 10.10.10.10 ... and then:

iptables -A INPUT --protocol tcp --dport 9999 -j DROP

... to DROP tcp connections to example port 9999 from any other IP.

Notice that the none specific protocol/port INPUT DROP rule that you chose to add:

iptables -A INPUT -j DROP

... will do the job as well although not limited to TCP/PORT.

Or

Insert (as the first rule "default") to the default policy INPUT chain:

iptables -I INPUT --protocol tcp --dport 9999 \! --source 10.10.10.10 -j DROP

... to DROP tcp connections to example port 9999 unless the source IP is 10.10.10.10 for example.

Notice

It's generally recommended (for readability/traceability/maintenance and sometimes performance) to avoid using the default policy chains for user added custom rules ... So, creating separate new custom chain(s) for that purpose is strongly recommended.

BUT

IPv4

Your source IP address may not actually be seen by your server as you expect, but rather as another IP address ... That can result from certain commonly implemented networking procedures like NATing, forwarding ... etc. ... So, check and confirm what your server sees as the IP address for your client.

IPv6

Your connection might be routed as IP version 6 or might be tunneled as IP version 6 and thus handled by ip6tables rules (check ip6tables -L) instead of iptables rules which will have no effect on IP version 6 connections ... So, check and confirm that to act accordingly.

0

I have included my own firewall configuration which you may find useful. It is intended for my laptop when I am on unprotected networks such as public wifi but also works locally due to trusted subnet configuration.

/etc/iptables/rules.v4

#-------------------------------------------------------------------------------
# IPTABLES firewall configuration, to minimize attack surface while allowing
# relevant incoming traffic

# The strategy is as follows:
# a) Early DROP of incoming malicious traffic in PREROUTING channel, using 
#    tables "raw" and "mangle"
# b) Default policy for INPUT chain is "DROP" - ACCEPT select traffic only
# c) Default policy for OUTPUT chain is "ACCEPT" - drop select traffic only
# d) Expose local services to trusted networks only
# e) Minimize multi/broad cast announcements to LAN as much as possible
# f) Log potentially malicious traffic, in a way that support analysis
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
# Table "raw" : early drop of incoming malformed packets with potentially
# malicious purpose. Table "raw" can only handle packets that does not require
# connection tracking
#-------------------------------------------------------------------------------
*raw
:PREROUTING ACCEPT
:OUTPUT ACCEPT
:raw-xmastree - 
:raw-rpfilter - 
:raw-martian -

# Drop & log incoming malformed "Xmas tree" packets with conflicting TCP flags
-A PREROUTING -p tcp -m tcp --tcp-flags ALL FIN,PSH,URG -j raw-xmastree

# Drop & log incoming TCP  packets which fail reverse path test (unroutable source address)
-A PREROUTING -p tcp -m rpfilter --invert -j raw-rpfilter

# N.B. Use of rpfilter rule w. UDP traffic, was found to break Wireguard VPNs ?
#-A PREROUTING -p udp -m rpfilter --invert -j raw-rpfilter

# Drop & log incoming packets from 127.0.0.0/8, which are NOT from loopback interface
-A PREROUTING ! -i lo -s 127.0.0.0/8 -j raw-martian

# raw-xmastree log and drop chain definition
-A raw-xmastree -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "[MYFW RAW-XMASTREE] "
-A raw-xmastree -j DROP

# raw-rpfilter log and drop chain definition
-A raw-rpfilter -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "[MYFW RAW-RPFILTER] "
-A raw-rpfilter -j DROP

# raw-martian log and drop chain definition
-A raw-martian -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "[MYFW RAW-MARTIAN] "
-A raw-martian -j DROP

COMMIT

#-------------------------------------------------------------------------------
# Table "mangle" : early drop of incoming malformed packets with potentially
# malicious purpose. Table"mangle" can handle rules with connection tracking
#-------------------------------------------------------------------------------
*mangle
:PREROUTING ACCEPT
:INPUT ACCEPT
:FORWARD ACCEPT
:OUTPUT ACCEPT
:POSTROUTING ACCEPT
:mangle-invalid - 
:mangle-tcpmss - 
:mangle-synplus - 

# Drop & log incoming packets with INVALID connection state
-A PREROUTING -m conntrack --ctstate INVALID -j mangle-invalid

# Drop & log NEW incoming TCP packets with invalid TCP mss value
-A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j mangle-tcpmss

# Drop & log NEW incoming TCP packets with invalid TCP flag combination (SYN+)
-A PREROUTING -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j mangle-synplus

# Drop (no log) incoming UDP Service Discovery (SSDP) mulitcasts to port 1900 
# (not working in filter table for some reason)
-A PREROUTING -d 239.255.255.250/32 -p udp --dport 1900 -j DROP

# Drop (no log) incoming UDP mDNS/bonjour/zeroconf multicasts to port 5353 
# (prevent DNS cache poisoning)
-A PREROUTING -d 224.0.0.251/32 -p udp --dport 5353 -j DROP

# mangle-invalid log & drop chain definition
-A mangle-invalid -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "[MYFW MANGLE-INVALID] "
-A mangle-invalid -j DROP

# mangle-tcpmss log & drop chain definition
-A mangle-tcpmss -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "[MYFW MANGLE-TCPMSS] "
-A mangle-tcpmss -j DROP

# mangle-synplus log & drop chain definition
-A mangle-synplus -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "[MYFW MANGLE-SYNPLUS] "
-A mangle-synplus -j DROP

COMMIT

#-------------------------------------------------------------------------------
# Table "filter" : default INPUT chain policy is "DROP".  Consequently, all 
# desired incoming traffic must have an explicit ACCEPT rule.
#-------------------------------------------------------------------------------
*filter
:INPUT DROP
:FORWARD ACCEPT
:OUTPUT ACCEPT
:filter-drop - 
:filter-accept - 
:filter-log -
:filter-wgleak -

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# INPUT chain ACCEPT rules - accept desired ingoing traffic only, and DROP rest
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# Troubleshooting rule.  To be disabled unless for troubleshooting
#-A INPUT -j filter-log

# Default rule : accept traffic from established (from inside -> outwards) 
# and related connections
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Accept all incominig traffic to loopback interface
-A INPUT -i lo -j ACCEPT

# Accept & log incoming ssh traffic from ipset "TrustedSubnets"
# N.B. sshd must use a hardened configuration

-A INPUT -p tcp -m set --match-set TrustedSubnets src -m multiport --dports 22,443 -j filter-accept

# Accept incoming SAMBA traffic from local IP addresses to local IPs on this host
-A INPUT -p tcp -m addrtype --src-type LOCAL --match multiport --dports 139,445 -j ACCEPT
-A INPUT -p udp -m addrtype --src-type LOCAL --match multiport --dports 137,138 -j ACCEPT

# Accept incoming Dropbox announcements from ipset "TrustedSubnets"
-A INPUT -p udp --sport 17500 --dport 17500 -m set --match-set TrustedSubnets src -j ACCEPT

# Accept incoming traffic from "all hosts" multicast IP address 224.0.0.1 (e.g. IGMP)
-A INPUT -d 224.0.0.1 -j ACCEPT

# Accept select subset of incoming icmp message types
-A INPUT -p icmp --icmp-type echo-request -m set --match-set TrustedSubnets src -j ACCEPT
-A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
-A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
-A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT

# N.B. Fallthrough DROP & LOG rule - must ALWAYS be last rule of the INPUT chain
-A INPUT -j filter-drop

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# OUTPUT chain DROP rules, to minimize "visibility" of host on the network
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# N.B. default policy for OUTPUT chain is ACCEPT !

# N.B. the next two rules block all outgoing SAMBA traffic that are not destined for a local 
# network interface IP address, including SAMBA multicasts to the default LAN

# Drop & log outgoing SAMBA traffic that is NOT destined for LOCAL IP addresses 
-A OUTPUT -p tcp -m addrtype ! --dst-type LOCAL --match multiport --dports 139,445 -j filter-drop
-A OUTPUT -p udp -m addrtype ! --dst-type LOCAL --match multiport --dports 137,138 -j filter-drop

# Drop & log outgoing Dropbox traffic not destined for ipset "TrustedSubnets",
-A OUTPUT -p udp --dport 17500 -m set ! --match-set TrustedSubnets dst -j filter-drop

# All other outgoing traffic is ACCEPTED due to OUTPUT chain default policy

# Here follow user-defined channel definitions
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# filter-accept chain definition : log, then accept
-A filter-accept -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "[MYFW FILTER-ACCEPT] "
-A filter-accept -j ACCEPT

# filter-drop chain definition : log, then drop
-A filter-drop -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "[MYFW FILTER-DROP] "
-A filter-drop -j DROP

# filter-wgleak chain definition : log, then drop
-A filter-wgleak -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "[MYFW FILTER-WGLEAK] "
-A filter-wgleak -j DROP

# filter-log chain definition : log, then accept
-A filter-log -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "[MYFW FILTER-LOG] "
-A filter-log -j RETURN

COMMIT


add your own trusted subnets as shown below.  I seem to recall you need to install some "persistent----" packages
if not already done


/etc/iptables/ipsets:


create TrustedSubnets hash:net family inet hashsize 1024 maxelem 65536 comment bucketsize 12 initval 0xef3022c4
add TrustedSubnets 10.192.168.0/24 comment "My home LAN"

All logging of firewall is tagged [MYFW-........] and i set up syslog rule to grab these to separate logfile, which I use for a small web application on apache2 server to see what is going on.

I include a flowchart of iptables logic that I found on the internet which I find very helpful.

I would disable IPV6 entirely if not needed, to avoid making separate rules for that to, and I chose to disable UFW to get better control.

Iptables flowchart

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .