I'm trying to configure a microservice for my web application, which is hosted at ip address X.X.X.X. The microservice should only accept https connections from this web app.

I've tested the microservice as working from the webserver with liberal "allow everything" ip tables rules, but my rules below (specifically, the last 2) aren't letting me through.

Here's the head of my iptables rules at the moment:

#allow current ssh connection so we don't disconnect ourselves
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
#allow ssh traffic
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -j ACCEPT
#allow ssh web traffic only from nominated webserver
iptables -A INPUT -p tcp -s X.X.X.X/32 --dport 443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -d X.X.X.X/32 --sport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

I've double checked the X.X.X.X ip is correct, and the web app's proxy has the same IP (it's nginx on the same server). What am I screwing up?

Edit: output of iptables -L:

target     prot opt source               destination         
ACCEPT     tcp  --  X-X-X-X.rev.cloud.scaleway.com  anywhere             tcp dpt:https state ESTABLISHED

Does this mean that somehow my "source" ip isn't actually the source of the request I think I'm sending? (and is instead the scaleway VPS provider?)

1 Answer 1


If you just want a single IP then this should do it, in the most retentive way possible:

# iptables -P INPUT DROP
# iptables -P FORWARD DROP
# iptables -P INPUT DROP
# iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED --jump ACCEPT
# iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED --jump ACCEPT
# iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED --jump ACCEPT
# iptables -A INPUT -m conntrack --ctstate INVALID --jump DROP
# iptables -A FORWARD -m conntrack --ctstate INVALID --jump DROP
# iptables -A OUTPUT  -m conntrack --ctstate INVALID --jump DROP

# iptables -A INPUT --in-interface lo --jump ACCEPT
# iptables -A OUTPUT --in-interface lo --jump ACCEPT
# iptables -A INPUT -p tcp -m tcp --source  X.X.X.X/32 --dport 443 -j ACCEPT
# iptables -A INPUT-p tcp -m tcp --source  X.X.X.X/32 --dport 22 -j ACCEPT
# debugging rules to help you set up.
# iptables -A INPUT -j LOG
# iptables -A FORWARD -j LOG 
# iptables -A OUTPUT -j LOG  

and if you don't care about ipv6 just drop all those too apart from lo.

Basically whatever is accepted for input will be tracked and the output allowed as it is releated.

If you need DNS then this is extra, but if you are able to log in the logs should help you see what you are missing.

  • Still not getting through. I've made an edit to the original post.
    – Escher
    Commented Jan 15, 2018 at 8:53
  • Make sure you have the iptables -A INPUT -j LOG at the end. Then make a request and check your log file. It will show you exactly what was blocked including the source IP.
    – IamNaN
    Commented Jan 15, 2018 at 9:04
  • Got it now. I was screwing up by adding extra conntrack flags.
    – Escher
    Commented Jan 15, 2018 at 9:15
  • No worries. Yeah the first parts will drop everything (you don't need that for the OUTPUT rule but it also stops root sending packets out. The sends parts, as these are added in order set up the stateful part. Then just allow whatver in order of restrictiveness to the other rules and you should be ok. Don't forget about ipv6 too.
    – user168387
    Commented Jan 15, 2018 at 10:05

You must log in to answer this question.

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