# [SOLVED] iptables on a vps

## taopai

Hey Guys,

Recently i bought a vps and i'm setting it up. For the time being i'll use it only for ssh/irc, later in time maybe for something more.

So i want to set up iptables. I read few articles on Gentoo Wiki, and other pages as well, and came up with something like this:

```
#!/bin/bash

#basing on https://wiki.gentoo.org/wiki/Iptables

iptables -F

iptables -X

iptables -Z

#REJECT because: http://www.chiark.greenend.org.uk/~peterb/network/drop-vs-reject

iptables -P INPUT REJECT

iptables -P FORWARD REJECT

iptables -P OUTPUT ACCEPT

#default rules, why most sources accepts lo traffic on the second place?

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

iptables -A INPUT -i lo -j ACCEPT

iptables -A INPUT -m conntrack --ctstate INVALID -j REJECT

#i read somewhere that you should allow these.

#is it possible to shrink it into one-liner?

iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT

iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT

iptables -A INPUT -p icmp --icmp-type 11 -j ACCEPT

iptables -A INPUT -p icmp --icmp-type 12 -j ACCEPT

#my ssh is configured to listen on 443

#all how-to's for stateful firewalls allow it this way:

iptables -A INPUT -p tcp --dport 443 -j ACCEPT

#shouldn't it be like below? this question applies to icmp's above as well

iptables -A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT

#those are from old Gentoo-Wiki article

iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset

iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable

#what about ipv6? copy-paste?
```

Could you give me some advises?

Best regards,

Tao

UPDATE

Here are the rules i decided to go with. They are not that different from what's in the how-to's, but now at least i know why  :Smile: 

```
iptables -F

iptables -X

iptables -Z

iptables -P INPUT DROP

iptables -P FORWARD REJECT

iptables -P OUTPUT ACCEPT

iptables -A INPUT -i lo -j ACCEPT

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

#Because http://shouldidisableicmp.com/

iptables -A INPUT -p icmp -j ACCEPT

#SSH

iptables -A INPUT -p tcp --dport 443 -j ACCEPT

iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset

iptables -A INPUT -p udp -j REJECT
```

```
ip6tables -F

ip6tables -X

ip6tables -Z

ip6tables -P INPUT DROP

ip6tables -P FORWARD REJECT

ip6tables -P OUTPUT ACCEPT

ip6tables -A INPUT -i lo -j ACCEPT

ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

#Because http://shouldidisableicmp.com/

ip6tables -A INPUT -p icmpv6 -j ACCEPT

#SSH

ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT

ip6tables -A INPUT -p tcp -j REJECT --reject-with tcp-reset

ip6tables -A INPUT -p udp -j REJECT
```

Last edited by taopai on Mon Dec 05, 2016 8:42 am; edited 1 time in total

----------

## dataking

Here's a couple of things to consider.

 First and foremost, setups like this are completely subjective and depend on the level of security and privacy that you are attempting to achieve.  This lens can help you focus on other points below.

 Drop vs Reject:  The idea is that if you have ANY ports open to the world, then the value of DROP is debatable.  Ideally, you would allow connections ONLY from known sources, so that packets from anywhere else (unknown hosts) would be dropped and your target would appear offline.  If you don't care about this, and/or you have pinholes set to ACCEPT from anywhere, REJECT is probably just fine.

As for your questions about whether to include certain rules or not, TMTOWTDI (There's More Than One Way To Do It).

You can allow ICMP or not (completely subjective).  Bear is mind that if you disallow ICMP, certain tools like ping, tracert (on windows) etc. will be rendered mostly useless.  But there are ways around that.  And, if you find youself in need of those tools for a particular troubleshooting session, you can always turn ICMP back on.  I prefer to just leave it off.

I don't know exactly why the "lo" rules are there, other than to allow traffic to/from the localhost.  I tend to think they are a bit redundant, but I do see them in a lot of guides also.

```

#REJECT because: http://www.chiark.greenend.org.uk/~peterb/network/drop-vs-reject 

iptables -P OUTPUT ACCEPT 

```

Strictly speaking, you don't want to allow everything outbound.  Again, YMMV.  It also depends on whether this is strictly a host FW or a network FW that is directing traffic for protected hosts behind it.

```
iptables -A INPUT -m conntrack --ctstate INVALID -j REJECT 
```

AFAIK, this is completely redundant and should be handled by the default policy.  No real need to involve the conntrack module.

```
iptables -A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT
```

Again, just whether to involve the conntrack module or not.  Some (minimal) systems may not have the conntrack modules compiled.  Most modern, popular linux distros should have them, though.  One way or the other, you don't really need both.

```
#those are from old Gentoo-Wiki article 

iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset 

iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
```

Again, handled by the default policy.

One thing I would recommend is adding a logging rule.  It's convenient to know what you're dropping and what is passing.

This article has some good examples:  http://www.thegeekstuff.com/2012/08/iptables-log-packets/?utm_source=feedburner

----------

## NeddySeagoon

taopai,

I hope you have both IPv4 and IPv6 on your VPS.

Unless you test your firewall locally, one day, you will lock yourself out.

As the firewalls for IPv4 and IPv6 are completely separate, when you block yourself on IPv4, you can fix it over IPv6 and vice versa.

What threat model is your firewall part of the defence to? 

I'll be a bit of a heretic here and suggest that you may not need a firewall.

----------

## Hu

 *taopai wrote:*   

> I read few articles on Gentoo Wiki, and other pages as well, and came up with something like this:
> 
> ```
> #!/bin/bash
> ```
> ...

 As I seem to have to say in every thread about this, never ever use a bash script to initialize your firewall in production.  You can use this script for exposition and experimentation, but once you have your rules correct, you should use the Gentoo init system to manage loading them on startup.

 *taopai wrote:*   

> 
> 
> ```
> #default rules, why most sources accepts lo traffic on the second place?
> 
> ...

 Good question.  I prefer to put simple rules first, so that the kernel can quickly dispense with easy matches.  I expect that a module like conntrack, although optimized, is still more expensive than a simple interface match.

 *taopai wrote:*   

> 
> 
> ```
> #my ssh is configured to listen on 443
> 
> ...

 No, the first form is fine.  Per man iptables-extensions, the main states for a packet on the input chain are NEW, INVALID, RELATED, ESTABLISHED.  You already handled INVALID, RELATED, ESTABLISHED earlier in the rules, so any packet that gets to this point is NEW.  Since we know it is NEW, asking the kernel to verify that is just wasted work.

 *dataking wrote:*   

> I don't know exactly why the "lo" rules are there, other than to allow traffic to/from the localhost.  I tend to think they are a bit redundant, but I do see them in a lot of guides also.

 All IP traffic directed back to the local system has interface lo, even when the destination IP address is assigned to one of the real network interfaces.  Strange things can happen when a machine cannot communicate with itself over lo.  Advanced users may be able to disallow it safely, but the safe default is to allow all loopback traffic.

 *dataking wrote:*   

> 
> 
> ```
> #those are from old Gentoo-Wiki article 
> 
> ...

 That's not exactly true.  Yes, the default policy will REJECT those packets.  However, REJECT can generate a variety of different messages to the peer.  According to man iptables-extensions, icmp-port-unreachable is the default, so the second rule you quoted is redundant.  The first one is redundant in the sense that the traffic is rejected by the default policy even without that rule, but it is not redundant if OP cares about the specific message sent to the peer when the traffic is rejected.

----------

## dataking

@Hu - first of all, all relevant and salient points.  I only hope I can remember my initial responses to some of your thoughts long enough to type them into this post.   :Wink: 

 *Hu wrote:*   

> you should use the Gentoo init system to manage loading them on startup.

 

For my own edification, and perhaps that of others, can you elaborate on this a little and/or point to a Wiki link?  I would actually favor an automated solution versus a manual one, in the respect that typing fingers have a tendency to make repeated mistakes, while scripted dolutions only repeat mistakes until they are fixed.  Also, aren't most init scripts shell scripts?

 *Hu wrote:*   

>  *taopai wrote:*   
> 
> ```
> #default rules, why most sources accepts lo traffic on the second place?
> 
> ...

 

This is kind of what I was alluding to, although admittedly, I wasn't able to put it so eloquently. *Hu wrote:*   

> 
> 
>  *taopai wrote:*   
> 
> ```
> ...

 

Great info!

 *Hu wrote:*   

> 
> 
>  *dataking wrote:*   
> 
> ```
> ...

 So kinda what I said with some caveats....

----------

## charles17

 *dataking wrote:*   

> @Hu - first of all, all relevant and salient points.  I only hope I can remember my initial responses to some of your thoughts long enough to type them into this post.  
> 
>  *Hu wrote:*   you should use the Gentoo init system to manage loading them on startup. 
> 
> For my own edification, and perhaps that of others, can you elaborate on this a little and/or point to a Wiki link? 

 

Feel free to improve it: * https://wiki.gentoo.org/wiki/Iptables#Generating_firewall_rules_for_client wrote:*   

>  ... Store it in a safe place - it is only needed for setting up or for changing the firewall rules. As the firewall rules are saved and reloaded, there is no need to run the script after every boot. 

 

----------

## taopai

Thank you All for the input. As i'm only a hobbyist that recently returned to Linux it's very helpful.

@dataking

As this is not a production machine, rather a useful toy, to learn, and tunnel music streaming services at work  :Cool:  , i don't need to log firewall events. But someday i'll make a use of the link, thanks.

@NeddySeagoon

Yeah, i have both, v4 and v6. But i have KVM in the web admin panel, so i can lock myself out on both, like a lord.  :Wink:  I didn't define a threat model, i even don't know how to (yet, i put it on my to-learn list, it would be awesome if you could provide a link to a good how-to). I agree with you that i may not need a firewall, but how else can i learn how to configure it?

@Hu

Regarding last two rules, i took from Handling rejection part of http://gentoo-en.vfose.ru/wiki/Iptables/Iptables_and_stateful_firewalls. The default policy for INPUT there is DROP, so in that case it's not redundant. Thanks to you i'm starting to understand what i'm going to implement.  :Very Happy: 

Now i'm thinking about:

```
iptables -P INPUT DROP

...

#iptables -A INPUT -m conntrack --ctstate INVALID -j REJECT (i read somewhere that there's no proper way to reject invalid packages)

...

iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset 

iptables -A INPUT -p udp -j REJECT
```

If i understand this correctly, it's not redundant in this form, right?

I'm still not sure why there's tcp-reset. I started reading RFC793, so i hope i'll get to that soon.

And what about the icmp rules? Is it safe to ACCEPT just "-p icmp"? Or should i stick only with those four types? I couldn't find a way to handle it with only one rule, is there any?

Best regards,

Tao

----------

## NeddySeagoon

taopai,

I have a real rented server which I divide up into KVMs for my own use.  I don't have any out of band access, so I have to boot things in rescue mode when (not if) I mess up.

I like shorewall and shorewall6 for firewall setup.  Its a little easier to get things right, in my opinion anyway.

Its a compiler for iptables rules, so you still use iptables.  Think of it like writing assembly language rather than raw hex.

I don't have a good link for threat assessment.

Here's some questions ta ask yourself though.

Internal or external threats, or maybe both.

My systems mostly have two users.  Me and root, so I was not overly concerned with the dirtyCOW exploit.  I know the root password.

However, somebody that broke in as say the apache user, might also be able to run that exploit.     

So I have

```
/dev/shm on /tmp type tmpfs (rw,nosuid,nodev,noexec,noatime)
```

, the noexec, prevents random users from running things out of /tmp

If you want to deny your normal users running things from /home that can be mounted noexec too. Both /tmp and /home need to be their own filesystems. for this.

It makes it harder for someone who does break in from the outside to do anything.

They can install an open relay mail server to distribute spam but not execute it.

Defending from the outside.  Don't run any listening services you don't need.  That minimises the attack surface.

Set up ssh to deny all root logins and only permit key based user logins. You will need to use su or sudo to become root.

Don't run anything that uses clear text passwords, like telnet. 

Use sftp, never ftp.  

Do you really need to serve dynamic web pages?

Run a gentoo hardened system.  gresecurity, not SELinux.  This can protect against some whole classes of exploits.

I've just updated the kernel on one of my systems.  gresec has decided to kill mdadm, which stops it booting, since root is on mdadm raid.

You only have the services you need and make it difficult for an attacker to do anything, when they do get in.  Casual attackers (script kidies) will go away and find an easier box to play with.

To defend against a directed attack is harder.  You need to assume some motive and level of resources. 

A determined government will send the boys round to beat your secrets out of you.  Hardening your server won't help.

So what's the motive for a  directed attack and what resources will the attacker commit?

Your firewall does have a part to play in all this.  You can restrict incoming connections to the services you do use.  That al least will keep your logspam down.

Its about reducing the attack surface.

You can restrict outgoing connections in case a nasty thing does get in, it can't phone home.  Its one layer of the security onion.  

e.g. If you only ever expect connections from the UK on port 22, you can only allow UK IP addresses through your firewall on port 22.

Try using BBC iPlayer from a non UK IP.

Security is a compromise with usability.  Blocking all non UK connections will be OK until you need access from overseas.

What you need depends on your threat model and the security/usability tradeoffs you are prepared to make.

e.g. mounting /tmp noexec used to stop nvidia-drivers dead. It used to write something to /tmp then execute it. Its since fixed.  

It would be your choice in that situation. 

I'm using the UK as a worked example as I'm in the UK.

----------

## Hu

 *dataking wrote:*   

>  *Hu wrote:*   you should use the Gentoo init system to manage loading them on startup. 
> 
> For my own edification, and perhaps that of others, can you elaborate on this a little and/or point to a Wiki link?  I would actually favor an automated solution versus a manual one, in the respect that typing fingers have a tendency to make repeated mistakes, while scripted dolutions only repeat mistakes until they are fixed.  Also, aren't most init scripts shell scripts?

 Gladly.  The Gentoo init script for iptables, and I expect most other distributions do a similar thing, uses a helper program named iptables-restore to load the rules.  When it runs, either it succeeds and all the rules load or it fails and none of the rules load.  When you use a bash script, each rule can load or fail individually, depending on whether the individual lines are spelled properly and whether the kernel supports the features being accessed.  For example, suppose you had a system where you ACCEPT conntrack ESTABLISHED traffic inbound, but DROP all other inbound traffic.  Your system has a job that connects outbound (which is permitted by a very permissive ACCEPT OUTPUT chain), and relies on the ESTABLISHED rule to receive the peer's responses.  Now you upgrade to a newer kernel and somehow lose conntrack from your kernel configuration.  A shell script will load what rules it can, and fail to load those it cannot, such as the conntrack rule.  Now you have a permissive OUTPUT, DROP all input, and no ESTABLISHED rule.  The system can try to establish connections, but it drops all responses to those connections, so they never succeed.  As another case, you could have an ACCEPT rule that allowed whitelisted traffic, but failed to load due to a missing feature that was required to process the whitelisting (such as module iprange), causing all traffic to fall through to an INPUT DROP, preventing you from connecting even from addresses that were supposed to be on the whitelist.  With a bit of work, we could probably contrive a scenario where missing rules cause an unwanted fail-open instead of an unwanted fail-closed.

The init system avoids that by loading the rules atomically.  On systems where you prefer fail-closed, you can preload netfilter with a very restrictive ruleset, then let the Gentoo init script try to switch to your full ruleset.  The initial set is designed to be so simple it cannot fail to load (except perhaps if you compile out netfilter entirely).  The full ruleset, if it loads, makes the system production ready.  If it fails to load, the system is left in a known fail-closed state until someone comes to the console to fix it.  The choice of whether to have a failed load leave you with all-open or all-closed depends on your threat model.  Using a bash script to load whichever rules happen to work leaves you in a mixed state that is neither your initial policy nor your intended final policy.

 *taopai wrote:*   

> 
> 
> ```
> iptables -P INPUT DROP
> 
> ...

 Correct.

 *taopai wrote:*   

> I'm still not sure why there's tcp-reset. I started reading RFC793, so i hope i'll get to that soon.

 According to the iptables man page, tcp-reset is useful when you need to deal with systems that you want them to believe you are not running that service, such as identd.

----------

## taopai

Hello Guys,

Once again thank you for all the input. To sum up, i'm going to paste my firewall rules in the first post, should anyone stumble into this tread in future.

Best regards,

Tao

----------

## NeddySeagoon

taopai,

What is your logic behind

```
iptables -P OUTPUT ACCEPT 
```

That lets all the nasties phone home if they get in.

Its called a half open firewall, as everything is allowed out.

That's the way most home routers are though.

----------

## taopai

 *NeddySeagoon wrote:*   

> 
> 
> ```
> iptables -P OUTPUT ACCEPT 
> ```
> ...

 

Well, for the time being there's only SSH running on the server, so the nasties don't have much space to show off, at least i hope so. I guess in some point in the future, i'm going to need rules for outbound traffic as well, but for now it should be enough as it is.

But if you have any suggestions, i'm looking forward to them  :Smile: 

Best regards,

Tao

----------

## NeddySeagoon

taopai,

I can post my shorewall rules file if you ask later.

Its full of commented out entries that make it difficult to read and it covers four separated subnets, so you only need about 25% of it.

Feel free to poke me in PM later and I'll clean it up and post it.

----------

## taopai

Hey NeddySeagoon,

I guess i missed the "PM later" part  :Smile: 

If your offer still stands, please post the shorewall rules. If you need me to poke you after standard business hours, i'll try to remember to do it. But it's close to Christmas, lots of preparations going on, so it's easy to forget  :Smile: 

Best regards,

Tao

----------

## dataking

 *taopai wrote:*   

> @datakingAs this is not a production machine, rather a useful toy, to learn, and tunnel music streaming services at work  , i don't need to log firewall events. But someday i'll make a use of the link, thanks.

 

I'd still recommend adding a logging rule......especially if/when you decide to change the default policy for the OUTPUT chain.

P.S.

Moja dziewczyna jest z Polski. Ma rodzinę w Warszawie.

----------

