View previous topic :: View next topic |
Author |
Message |
kgdrenefort Guru
Joined: 19 Sep 2023 Posts: 312 Location: Somewhere in the 77
|
Posted: Tue Apr 30, 2024 9:42 am Post subject: [SOLVED] An idiot try nftables |
|
|
Hello,
So, to keep on the up-to-date good way of doing things, I find out it's not a good things to use iptables anymore. New cool toy seems to be ntftables.
What a pain !
First things first: I'm not very good with network, to stay nice.
Before, I was doing an iptables conf file just sending the rules at each boot while a service was made to be enabled and run theses rules. Was perfectly working, specially my needs were merely to disable everything and allow 80/443/22, plus a few stuff as ICMP.
It seems almost the same with nftables, from what I read on the wiki, but way more sophiscated (and complicated).
From what I understand, it works with at least a configuration files, which can call other modules files with their own sets of rules (DCHP, ICMP, SSH…).
So far as I was used to, there was three type of rules (with IPTables): IN, OUT and FORWARDED.
I tried to follow this page, by doing the magic thinking (while reading a bit what it was adding) and so from the wiki page I have now theses files:
- /etc/nftables.rules
- /etc/nftables.conf.d/:
00-definitions.rules 01-drop-policy.rules 01-icmp.rules 05-dhcp.rules 05-lan-nat.rules 21-ntp.rules 22-ssh.rules
Without modification from the wiki.
Then I try to test the configuration, and the first problem arise:
Code: | Mephistopheles /etc # nft -c -f nftables.rules
Mephistopheles /etc # nft -c -f nftables.conf.d/00-definitions.rules
Mephistopheles /etc # nft -c -f nftables.conf.d/01-drop-policy.rules
Mephistopheles /etc # nft -c -f nftables.conf.d/01-icmp.rules
nftables.conf.d/01-icmp.rules:14:14-26: Error: No such file or directory
ip saddr @trusted_nets icmp type $trusted_icmp_types counter accept
^^^^^^^^^^^^^
nftables.conf.d/01-icmp.rules:15:14-26: Error: No such file or directory
ip daddr @trusted_nets icmp type $trusted_icmp_types counter accept
^^^^^^^^^^^^^
|
So, the wiki says:
Code: | If this error is printed for every chain of a table definition make sure, that the table's family is available through the kernel. This happens for example if the table uses family inet and the kernel configuration did not enable mixed IPv4 and IPv6 rules (CONFIG_NF_TABLES_INET). |
Do I have really to modify my kernel for something trivial as a firewall ?
Honnestly, that makes me want to drop it, if I need to modify the kernel to allow a firewall to works, in this case with a mix of IPv4 & IPv6…
I am not opening this topic to vent ! But it is really necessary to suffer to block everything and only allow a few services ?
Should I, from what I read, check and, if so, modify my kernel and recompile it ?
Regards,
GASPARD DE RENEFORT Kévin _________________ Traduction wiki, pour praticiper.
Custom logos/biz card/website.
Last edited by kgdrenefort on Thu May 16, 2024 9:23 am; edited 1 time in total |
|
Back to top |
|
|
kgdrenefort Guru
Joined: 19 Sep 2023 Posts: 312 Location: Somewhere in the 77
|
Posted: Tue Apr 30, 2024 9:51 am Post subject: |
|
|
Code: | Mephistopheles /etc # zgrep CONFIG_NF_TABLES_INET /proc/config.gz
CONFIG_NF_TABLES_INET=y
|
Is present.
So it's not a missing module/parameter in kernel.
So it would be a configuration problem, will take a new look at wiki in hope I understand.
Regards,
GASPARD DE RENEFORT Kévin _________________ Traduction wiki, pour praticiper.
Custom logos/biz card/website. |
|
Back to top |
|
|
kgdrenefort Guru
Joined: 19 Sep 2023 Posts: 312 Location: Somewhere in the 77
|
Posted: Tue Apr 30, 2024 10:04 am Post subject: |
|
|
After some talking on #gentoo-chat, it could be all ok in the end.
I'm checking files individualy, but if one of these is requesting stuff from other, it will fails because there are not presents.
So, it's just needed to check from /etc/nftables.rules, is that right ?
Regards,
GASPARD DE RENEFORT Kévin _________________ Traduction wiki, pour praticiper.
Custom logos/biz card/website. |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5094 Location: Bavaria
|
|
Back to top |
|
|
kgdrenefort Guru
Joined: 19 Sep 2023 Posts: 312 Location: Somewhere in the 77
|
Posted: Wed May 01, 2024 12:32 pm Post subject: |
|
|
Thanks for you reply, will keep it in case I'm really too slow to make it myself .
Now I'm in despair to find some «NFTables for dummies» paper, also considering my «jump into the pit» way: Push hard and harder until, by example and try, it works. That is not the best way for your mental health too !
By the way, this is the actual IPTables I use:
Code: | Chain INPUT (policy ACCEPT)
target prot opt source destination
f2b-sshd tcp -- anywhere anywhere multiport dports ssh
ACCEPT all -- anywhere anywhere
REJECT all -- anywhere 127.0.0.0/8 reject-with icmp-port-unreachable
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:https
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
ACCEPT icmp -- anywhere anywhere icmp echo-request
LOG all -- anywhere anywhere limit: avg 5/min burst 5 LOG level debug prefix "iptables denied: "
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
Chain f2b-sshd (1 references)
|
After it's a giant list of banned IP. Not relevant IMHO.
It is made from this file:
Code: | *filter
# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT
# Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allows all outbound traffic
# You could modify this to only allow certain traffic
-A OUTPUT -j ACCEPT
# Allows HTTP and HTTPS connections from anywhere (the normal ports for websites)
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
# Allows SSH connections
# The --dport number is the same as in /etc/ssh/sshd_config
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT
# Now you should read up on iptables rules and consider whether ssh access
# for everyone is really desired. Most likely you will only allow access from certain IPs.
# Allow ping
# note that blocking other types of icmp packets is considered a bad idea by some
# remove -m icmp --icmp-type 8 from this line to allow all kinds of icmp:
# https://security.stackexchange.com/questions/22711
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
# log iptables denied calls (access via 'dmesg' command)
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
# Reject all other inbound - default deny unless explicitly allowed policy:
-A INPUT -j REJECT
-A FORWARD -j REJECT
COMMIT
|
By the way, I'm not asking someone to do it for me, this topic is between personnal notes shared (in case someone sees something goofy) and hope to have the link/stuff that helps me understand.
Regards,
GASPARD DE RENEFORT Kévin _________________ Traduction wiki, pour praticiper.
Custom logos/biz card/website. |
|
Back to top |
|
|
kgdrenefort Guru
Joined: 19 Sep 2023 Posts: 312 Location: Somewhere in the 77
|
Posted: Wed May 01, 2024 1:21 pm Post subject: |
|
|
After writing this, I realize it's… blurry, but that will allows you to take a look into my sick mind .
So, if I understand, NFTables works this way:
Tables that contains chains that contains rules that contains an or several actions to apply.
A tables is a whole sets of chains.
A chains is a set of rules.
A rules contains one or more actions regarding what is presented to it, the condition.
Lastly, the action is what is made of this request (forward it, accept it, reject it, maybe logs it…).
Example:
I open to internet port 22 for SSH, I would have a table for the SSH rules in general in my NFTables. Another one for HTTP (and maybe another one for HTTPS ?), another one for MariaDB, etc…
This tables will contains different chains, for different type of request, a service in this case, working on different ports and protocoles (TCP/UDP, or none in ICMP case).
A request for SSH will be presented from a non-allowed IP.
The request is taked care by the ssh tables, that will pass it to a chain, then the request will be, as in an if-else statement in programing be oriented to the proper rule (it's an example). Here, the rules see an allowed protocole/port/service, SSH, but for a non-allowed IP, so it'll apply an action from a rule dedicated to these non-allowed request. Rejecting it.
Or simply: Non-allowed SSH request is oriented in SSH tables, containing all chains for taking care of it, NFTables does not sees it in an allowed-list and then reject it.
To achieve that, a table have to be created, then it's chains, with for each a rule that is doing from my config an ACCEPT, REJECT or anything else needed. In this case, REJECT to drop that non-desired request.
Or another way, to sees it:
Tables: SSH
SSH tables would contain: A chain that is stating that SSH is on an opened port (22), for TCP/UDP protocols only.
A reject rules (among other): If the IP requesting to access port 22 (TCP/UDP) for SSH service is redirected to it, it will check it's own rule.
Reject rules: Not an allowed IP as request, action is take.
Non allowed request action: REJECT (block/drop it).
The big difference, among other, from IPTables:
While, IPTables, would be way more simple and simply take the request and apply the action against a rule, in a single file mostly, making it hard for big networks or even for complex sets, while NFTable allow you to:
Separate your config among several files, each of them has it's role to play, for a specific service. While IPTables is a single file methods, without allowing you to create variable-likes naming for what you want, making it deeply confusing in some cases.
The main configuration file could be at /etc, then a subfolder contains other configuration file (if desired, I guess it's an allowed choice to separate, not an obligation as you would see from a nginx.conf file separating host and document roots in other config file). The main is merely asking to check these other config file after it blocked by defaults everything and declare the tables that would be used.
Each tables (named and declared in the main config file) is a reference to one of these sub-config file, that would be read when needed (probably not the proper way to sees it, but that is how I do for now). To keep my example, the main file will say a SSH table exist (and I have to create it myself, because it's a subconfig file). So we can see a subconfig file as a sets of rules, contained into a table file.
Then when a request is made to SSH, it's redirected to that table file (XX-ssh.rules for example), which will separate the differents actions (ACCEPT, REJECT, etc) among it's chains, into the tables (which is a file).
The table, which is just a convenient way to declare a sets of request, chains are kind of if-statement condition, if it gets a request for it (from the condition into the table file), it'll compare it agains several rules. So main file is declaring tables, which are separated file (if wanted), containing if-else like (still an example, not the best) chains, which are matched against the request (IP, protocole, ports, the content…).
Each chain would then redirect the request to a rule, where a request is (according to it's condition) taken care of by action(s). The rule can be seen as a case, like a switch-case in programming too, for example. Once a chain forward the request to the rule, it simply apply what the administrator asked (ACCEPT, REJECT…). That is the action that is the final process, before it's just a workflow to redirect the request to the proper action.
Is it… Correct, more or less ? I guess what I try to say in this replies is full of approximations, I miss in the process the concept of hook, which once translated to french makes me things of something that grab another thing, like a fish or an annoying kid.
My head hurts !
PS: After 10 reading of my post, I can't explain what I think I understood better, sorry.
Regards,
GASPARD DE RENEFORT Kévin _________________ Traduction wiki, pour praticiper.
Custom logos/biz card/website. |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5094 Location: Bavaria
|
Posted: Wed May 01, 2024 2:31 pm Post subject: |
|
|
kgdrenefort,
iptables and nftables do the same job: Giving some rules to the kernel. Yes, the kernel is the firewall.
A table is a hook to a special protocol. You dont see different tables in iptables BECAUSE iptables handels ONLY IPv4 traffic. The same is true for ip6tables. With nftables you can handle many different protocols - so, you can define more tables; e.g a table for filtering IPv4, and a table for filtering IPv6, and a table for inet (tables of this family see both IPv4 and IPv6 traffic/packets, simplifying dual stack support), and a table for ARP (in the past this was handled from arptables).
A chain is a hook to the appropriate Netfilter hook. With iptables you have 3 pre-defined chains ... you dont have with nftables. Here you have define them yourself (most Users of nftables use the same names: INPUT, OUTPUT and FORWARD, haha).
And yes, these chains contains your rules.
One difference most user dont understand when switching from iptables to nftables is:
With iptables you can mix your chains when defining rules. This is possible in a script:
Code: | iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT |
This is not possible with nftables because you must define the policy, all chains with all rules in one "section"; e.g.:
Code: | table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# accept any localhost traffic
iif lo accept
# accept traffic originated from us
ct state established,related accept
# accept neighbour discovery otherwise IPv6 connectivity breaks
icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
}
} |
Some hints:
1. To get iptables-translate and iptables-restore-translate you must emerge "iptables" with Use-flag "nftables"
2. Your two outputs do not match (I dont see the definition of the chain "f2b-sshd")
3. I recommend to set the default policy to DROP for Input (dont inform bad sites from the internet == silently drop the packet; every big company does the same). You can set the default policy with -P (iptables -P INPUT DROP.
4. If you want allow all outbound traffic == You dont want filter what your local applications do THEN you can set the default policy to ACCEPT for Output. Then you dont need the rule "-A OUTPUT -j ACCEPT"
If you would filter also outbound traffic then I recommend to set the default policy to REJECT (because you want inform your local application about). Filtering outgoing traffic is a separate topic that I don't want to go into now.
5. If you dont have forwarding (needs 2 or more interfaces) THEN you dont need any rule in chain FORWARD (there is no connection to the loopback). To be on a absolute safe side you can also set the default policy to DROP.
6. You dont need INPUT ! -i lo -d 127.0.0.0/8 -j REJECT
7. If you have a (A)DSL-MODEM-Router with integrated FireWall then you dont need "-m state --state NEW" for your sshd-rule. Every packet belonging to an ESTABLISHED session, will be accepted by this rule: "A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT" and every INVALID packet is dropped by your router.
8. You can watch the number of packets with "iptables -L -vn" to see which rule was triggered. This is important to see what is the best order for your rules: Set the accepting rules with the most traffic first. Example:
Code: | # iptables -L -vn
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
170M 204G ACCEPT 0 -- lo * 0.0.0.0/0 0.0.0.0/0
98M 201G ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT 6 -- * * 192.168.2.4 0.0.0.0/0 tcp dpt:22
3488 126K DROP 2 -- * * 0.0.0.0/0 0.0.0.0/0
0 0 LOG 0 -- * * 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix "!!! DROP " |
(Yes, this is my complete input chain; I dont have a Webserver like you on this machine)
- I have more traffic on Loopback so it is my first rule. I allow connection to my sshd ONLY from another (Admin-) Station.
- Before I log any packet I drop silently (without logging) useless packets (protocol 2 is IGMP Internet Group Management Protocol coming from my router) to have a clean message-log.
9. I never recomend to allow incoming connections to the sshd from the internet. If you really need remote access THEN use a VPN. (Yes, I know fail2ban, but I dont think it is sufficent.) _________________ https://wiki.gentoo.org/wiki/User:Pietinger |
|
Back to top |
|
|
kgdrenefort Guru
Joined: 19 Sep 2023 Posts: 312 Location: Somewhere in the 77
|
Posted: Wed May 01, 2024 3:04 pm Post subject: |
|
|
Thanks for such a complete and time-consumming answer !
About a few points (because I'll have to re-read all that later to assimilate it a bit):
2. Simply because it's probably made from fail2ban and added to it, in addition to my rules:
Code: | fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 141
| |- Total failed: 17042
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 414
|- Total banned: 3646
`- Banned IP list:
(… … … Giant list of banned IP … … …)
|
So it's normal to not sees it in my output, didn't thinked of that.
7. Having optic fiber bandwitdh with what seems to be a proper router from my ISP, but nothing professionnal.
9. Sure, it's better, but I do not prioritize it for now because it's local, it's also a two-weeks a year needs, 50 other weeks I'm at home :).
If I do, tho, open SSH, it's with fail2ban with very restrictive rules to get banned very fast, with an SSH key and a password. Only allowing a single user to connect and disabling password auth and non-key auth.
This way is pretty much secure against script and brute force, to not say impossible to break. But if there is a 0-days, or if I forgot one of these points, well, dumb me because it would be trouble !
Since last reboot, +17k failed attempt, 414 are currently banned. Seems effective, at least against bot and such.
Regards,
GASPARD DE RENEFORT Kévin _________________ Traduction wiki, pour praticiper.
Custom logos/biz card/website. |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5094 Location: Bavaria
|
Posted: Wed May 01, 2024 3:14 pm Post subject: |
|
|
kgdrenefort wrote: | Thanks for such a complete and time-consumming answer ! |
You are very Welcome !
kgdrenefort wrote: | 9. Sure, it's better, but I do not prioritize it for now because it's local, it's also a two-weeks a year needs, 50 other weeks I'm at home . |
Hmmm ... I dont thinks it is local ... with this you can make it local for 50 weeks (check your local network address; and dont forget to activate the old rule before you leave )
Code: | # accept ssh from local network only
iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT |
_________________ https://wiki.gentoo.org/wiki/User:Pietinger |
|
Back to top |
|
|
kgdrenefort Guru
Joined: 19 Sep 2023 Posts: 312 Location: Somewhere in the 77
|
Posted: Thu May 02, 2024 10:14 am Post subject: |
|
|
Quote: | To get iptables-translate and iptables-restore-translate you must emerge "iptables" with Use-flag "nftables" |
1. That is if I want to use this tool to do the translation for me. But nice to know.
Quote: | I recommend to set the default policy to DROP for Input (dont inform bad sites from the internet == silently drop the packet; every big company does the same). You can set the default policy with -P (iptables -P INPUT DROP. |
3. So everything will be DROP (rejected) by defaults, which is kind of the desired behavior for a server and a firewall, then I open what is needed. That was the meaning of this point ?
Quote: | If you want allow all outbound traffic == You dont want filter what your local applications do THEN you can set the default policy to ACCEPT for Output. Then you dont need the rule "-A OUTPUT -j ACCEPT"
If you would filter also outbound traffic then I recommend to set the default policy to REJECT (because you want inform your local application about). Filtering outgoing traffic is a separate topic that I don't want to go into now. |
4. Is it important, regarding security, to also filter what's going out of the server (outbound traffic) ? Maybe if you get pwned it could mitigate a bit what's going on, depending how deeply the intrusion is (if the attacker gets root access, anyway, that is not relevant since the attacker would disable my firewall or modify it, anyway ?).
You also say you don't want to go deeply in this subject, no problem, but I'm curious on the pro and cons of filtering or not filtering the outbound traffic.
Quote: | If you dont have forwarding (needs 2 or more interfaces) THEN you dont need any rule in chain FORWARD (there is no connection to the loopback). To be on a absolute safe side you can also set the default policy to DROP. |
5. I only got one ethernet card, but I'll use (probably) virtual machines (at least one, at least at the begining, but I would like to separe different services among different VM), so the host will have it's own hardware interface and the VM will have their own IP and so, a virtual ethernet device. But all will be anyways go into the host interface. Not sure on this point tho.
Quote: | 6. You dont need INPUT ! -i lo -d 127.0.0.0/8 -j REJECT |
6. This rules is, I guess: Block every input for loopback (localhost) interface. Which is I guess not desired, yes.
Quote: | 7. If you have a (A)DSL-MODEM-Router with integrated FireWall then you dont need "-m state --state NEW" for your sshd-rule. Every packet belonging to an ESTABLISHED session, will be accepted by this rule: "A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT" and every INVALID packet is dropped by your router. |
7. I'm using a Freebox POP, I translated this bit from their website (in french) about advanced features:
https://assistance.free.fr/articles/354:
Code: |
Once the Freebox routeur is enabled, advanced features are available:
IP address of the Freebox: Define the IP of your Freebox in case you choose to manually configure it.
Enabled DHCP: In enabled DHCP mode, the Freebox gives automaticaly the IP address to computers connected to it.
DHCP Start/End: Customize the numbers of connected computer (if enabled DHCP). If 4 computers are connected, you can dehfine 192.168.0.1 (start) and 192.168.0.4 (end).
DMZ IP address: Open all ports to the stated IP.
To disable the DMZ, you have to enter an IP address where the last byte (last address number) is 0.
Answer to ping: in enabled mode, it allows to ping (ask) the Freebox from outside.
WOL proxy: Allow the wake on lan, meaning turning on the computer from your network.
Port forwarding: Open all choosen ports on your computer (via it's IP).
Forwarding range ports: Same options but for a range of ports.
Permanent DHCP lease ([u]not sure of the translation here…): Allow DHCP to attribute an IP address regarding the desired MAC address.
Baux DHCP permanents : permet au DHCP d'attribuer une adresse IP précise en fonction de l'adresse MAC voulue.
|
That is not complete, will dig into it.
Quote: | You can watch the number of packets with "iptables -L -vn" to see which rule was triggered. This is important to see what is the best order for your rules: Set the accepting rules with the most traffic first. Example:
Code: | # iptables -L -vn
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
170M 204G ACCEPT 0 -- lo * 0.0.0.0/0 0.0.0.0/0
98M 201G ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT 6 -- * * 192.168.2.4 0.0.0.0/0 tcp dpt:22
3488 126K DROP 2 -- * * 0.0.0.0/0 0.0.0.0/0
0 0 LOG 0 -- * * 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix "!!! DROP " |
(Yes, this is my complete input chain; I dont have a Webserver like you on this machine)
- I have more traffic on Loopback so it is my first rule. I allow connection to my sshd ONLY from another (Admin-) Station.
- Before I log any packet I drop silently (without logging) useless packets (protocol 2 is IGMP Internet Group Management Protocol coming from my router) to have a clean message-log. |
8. I never had to do that, but since I understood that NFTable reads things in a certain manner, it has it's importance.
Quote: | I never recomend to allow incoming connections to the sshd from the internet. If you really need remote access THEN use a VPN. (Yes, I know fail2ban, but I dont think it is sufficent.) |
9. To get back to it, I do not desire a VPN for now, and I'm aware using a VPN is more secure, but that also means more works. I think that is a very nice features for security, but too much (and too quick) is always bad. I mean, that is not in my opinion the priority about security. Specially it's not professionnal or critical hosting. It'll be set, probably later.
Quote: | Hmmm ... I dont thinks it is local ... with this you can make it local for 50 weeks (check your local network address; and dont forget to activate the old rule before you leave :lol: ) |
I might misexplained my point: There is about 2 weeks a year I need to have SSH open to the internet. Even my fiancée which is pushing some update on a few website is on the same networks. For these two weeks, I need access in case of problem, but I could also not need to connect. My fear would be if the association website I host is in trouble and there is no need to proximity, well at least the website won't stay down for long. Would be a shame, to me, to have a few days (or more !) of this website down. So, having a VPN (and it's configuration to make) for two weeks is a bit, IMHO, overkill. Still I'm interested to made one so…
Regards,
GASPARD DE RENEFORT Kévin _________________ Traduction wiki, pour praticiper.
Custom logos/biz card/website. |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5094 Location: Bavaria
|
Posted: Thu May 02, 2024 1:16 pm Post subject: |
|
|
First of all: A Firewall is only ONE piece of many to secure a machine. Other pieces are: a hardened Kernel, a MAC like SELinux or AppArmor, integrity Management (like IMA) and maybe also some efforts for privacy (DNS over TLS; Cookie handling in browser; ...)
kgdrenefort wrote: | 3. So everything will be DROP (rejected) by defaults, which is kind of the desired behavior for a server and a firewall, then I open what is needed. That was the meaning of this point ? |
No, there is a difference between DROP and REJECT: With REJECT the kernel will send an ICMP message back; with DROP the kernel does nothing else than dropping this packet == no response to the sender.
kgdrenefort wrote: | 4. Is it important, regarding security, to also filter what's going out of the server (outbound traffic) ? Maybe if you get pwned it could mitigate a bit what's going on, depending how deeply the intrusion is (if the attacker gets root access, anyway, that is not relevant since the attacker would disable my firewall or modify it, anyway ?).
You also say you don't want to go deeply in this subject, no problem, but I'm curious on the pro and cons of filtering or not filtering the outbound traffic. |
It took me a long time to finally find a malicious website, but then my firewall stopped all attempts:
https://forums.gentoo.org/viewtopic-p-8669187.html#8669187
(Maybe look also into the first (german) and second (english) post of this thread.)
Pro and cons are easy to explain:
Pro: More Security
Cons: More work for defining the rules and setting up a proxy
kgdrenefort wrote: | 5. I only got one ethernet card, but I'll use (probably) virtual machines (at least one, at least at the begining, but I would like to separe different services among different VM), so the host will have it's own hardware interface and the VM will have their own IP and so, a virtual ethernet device. But all will be anyways go into the host interface. Not sure on this point tho.
7. I'm using a Freebox POP, I translated this bit from their website (in french) about advanced features: |
If you use forwarding THEN you really should filter this chain also. I suggest to do this in two steps:
1. Deny everything and log it. So you can see who tries to communicate.
Code: | iptables -F FORWARD
iptables -P FORWARD DROP
iptables -A FORWARD -j LOG --log-prefix "DROP FORWARD: " |
2. Now you will see in your message log some denies. If you now know which IP addresses are involved you allow only them (+ you will need also connection tracking for all reply packets):
Code: | iptables -F FORWARD
iptables -P FORWARD DROP
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Example:
iptables -A FORWARD -s W.X.Y.Z -d A.B.C.D -p tcp --dport ??? -j ACCEPT
# More accepts:
...
iptables -A FORWARD -j LOG --log-prefix "DROP FORWARD: " |
kgdrenefort wrote: | 6. This rules is, I guess: Block every input for loopback (localhost) interface. Which is I guess not desired, yes. |
Just check with "iptables -L -vn" HOW MANY packets were discarded by this rule ... _________________ https://wiki.gentoo.org/wiki/User:Pietinger |
|
Back to top |
|
|
kgdrenefort Guru
Joined: 19 Sep 2023 Posts: 312 Location: Somewhere in the 77
|
Posted: Thu May 02, 2024 2:23 pm Post subject: |
|
|
Wow, never thinked before I would read so much about packets, that's really the field I hate the most in IT !
That is interesting, but can't say I understood all of your old posts, but I have a link to bookmark for later reading when I would need it. Well made.
Quote: | Just check with "iptables -L -vn" HOW MANY packets were discarded by this rule ... |
Code: | 170M 204G ACCEPT 0 -- lo * 0.0.0.0/0 0.0.0.0/0 |
I guess M stands for… millions ? That is indeed a lot, but would ask: How much time it needs to reach this amount ?
Thanks for your time, again. Will soon try to test it with a VM and play around, poke the network once it'll be made (still have to figure out the best between a NAT and a bridge, shhhush, don't answer ! Don't kill the fun *).
Will try to setup inside a netfilter settings and open ports with dumb/fake service to try to reach these, will also force me to dig up some tools I almost never use.
* I will regret this, later.
Regards,
GASPARD DE RENEFORT Kévin _________________ Traduction wiki, pour praticiper.
Custom logos/biz card/website. |
|
Back to top |
|
|
Hu Administrator
Joined: 06 Mar 2007 Posts: 22625
|
Posted: Thu May 02, 2024 2:39 pm Post subject: |
|
|
kgdrenefort wrote: | Quote: | Just check with "iptables -L -vn" HOW MANY packets were discarded by this rule ... |
Code: | 170M 204G ACCEPT 0 -- lo * 0.0.0.0/0 0.0.0.0/0 | I guess M stands for… millions ? | Correct. Per man iptables: man iptables: | -v, --verbose
Verbose output. This option makes the list command show the in‐
terface name, the rule options (if any), and the TOS masks. The
packet and byte counters are also listed, with the suffix ’K’,
’M’ or ’G’ for 1000, 1,000,000 and 1,000,000,000 multipliers re‐
spectively (but see the -x flag to change this) |
kgdrenefort wrote: | That is indeed a lot, but would ask: How much time it needs to reach this amount ? | Many applications use IP-over-localhost, so you can accumulate a high count here fairly quickly. |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5094 Location: Bavaria
|
Posted: Thu May 02, 2024 2:48 pm Post subject: |
|
|
kgdrenefort wrote: | Quote: | Just check with "iptables -L -vn" HOW MANY packets were discarded by this rule ... |
Code: | 170M 204G ACCEPT 0 -- lo * 0.0.0.0/0 0.0.0.0/0 |
|
No, I have not meant this rule ... I have meant this rule:
Code: | -A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT |
(first I wrote you dont need it; then you answered in 6. where you thought you need it; then I asked you to verify it with checking the number of packets for this rule) _________________ https://wiki.gentoo.org/wiki/User:Pietinger |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5094 Location: Bavaria
|
Posted: Thu May 02, 2024 2:53 pm Post subject: |
|
|
kgdrenefort wrote: | [...] still have to figure out the best between a NAT and a bridge, [...] |
Yes, for NATting you will need another table in iptables because you do this with mangle ... for bridging have a look to ebtables (or nftables which does it all). _________________ https://wiki.gentoo.org/wiki/User:Pietinger |
|
Back to top |
|
|
kgdrenefort Guru
Joined: 19 Sep 2023 Posts: 312 Location: Somewhere in the 77
|
Posted: Thu May 02, 2024 4:59 pm Post subject: |
|
|
Thanks for your replies.
I have started to setup a proper trio with QEMU/LibVirt/Virt-Manager, my goal was to add it to my host and then do some testing with firewall.
But found out, as remembered because I did not does that in years, that I'll need at this point NAT or bridge.
After some reading, my conclusion is in this case I need NAT: It'll give to my VM it's personal private IP, while bridge will just gives an interface (e.g 'br0') to reach my VM. Which is probably not what I want, since I wanted to test connectivity between two machines, using VMs.
And that's the catch: I need a firewall configured ! Fat luck, it was to test it.
Turns out, as usual, I complicated my life, a lot, while I could simple run another low-power machine and try out. I have two laptop with Gentoo, one could be the firewalled machine and the other the reaching, or my host…
So, NAT is more convenient in my case, having it's own private IP in my network, would ease to me (I think !) to simulate interactions in my network.
At least, that is my conclusion.
Regards,
GASPARD DE RENEFORT Kévin _________________ Traduction wiki, pour praticiper.
Custom logos/biz card/website. |
|
Back to top |
|
|
toralf Developer
Joined: 01 Feb 2004 Posts: 3940 Location: Hamburg
|
Posted: Thu May 02, 2024 6:26 pm Post subject: Re: An idiot try nftables |
|
|
kgdrenefort wrote: | Hello,
New cool toy seems to be ntftables. | hhm, from https://en.wikipedia.org/wiki/Nftables: It has been available since Linux kernel 3.13 released on 19 January 2014. |
|
Back to top |
|
|
kgdrenefort Guru
Joined: 19 Sep 2023 Posts: 312 Location: Somewhere in the 77
|
Posted: Fri May 03, 2024 10:59 am Post subject: Re: An idiot try nftables |
|
|
toralf wrote: | kgdrenefort wrote: | Hello,
New cool toy seems to be ntftables. | hhm, from https://en.wikipedia.org/wiki/Nftables: It has been available since Linux kernel 3.13 released on 19 January 2014. |
Surely, but at the same times it takes years sometime to move on the new tools.
My last experience as sys. admin was off iptables 99,99% of the time, the firewall were managed by the NOC team.
Also, I had never heard somehow about NFTable, always thinked IPTables was widely used as the main firewall, almost everywhere on Linux.
Gentoo made me realize I was a lot out-to-date about some stuff, as firewall .
Regards,
GASPARD DE RENEFORT Kévin _________________ Traduction wiki, pour praticiper.
Custom logos/biz card/website. |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5094 Location: Bavaria
|
|
Back to top |
|
|
kgdrenefort Guru
Joined: 19 Sep 2023 Posts: 312 Location: Somewhere in the 77
|
Posted: Tue May 14, 2024 11:39 am Post subject: |
|
|
Hello,
Today I had the time to finish the comments on the file below.
It's merely to try to understand what parts are doing, which will surely helps me later to create the actual rules from the chains and table defined here. Could you, please, tell me if it's seems I understood a bit better what's going on in that file ?
Code: | #! /sbin/nft -f
flush ruleset # Clean the rules, there is nothing now
# Start by creating the netdev table, responsible for ALL incoming and outgoing traffic, that's where everything is taking care of
# first, before any allowing traffic. By default, drop everything (instead of reject) to silence them, it also act as
# the normal behavior for a non-existent service, such as reaching non-working service will does NOT answer back.
#
# It is more secure this way, because you have more difficulty to know if you (outside) are blocked, or if there is no
# actual service behind this port. Doing this make the target (me) less easy to be discovered for service that should
# NOT respond to anyone, such as SSH, MariaDB, etc.
# Define the table filter in the netdev family
# Here we drop everything, before creating table responsible to allow the "normal" and expected traffic
table netdev filter {
# Basic filter chain, devices can be configured to jump here
chain ingress_filter { # As a personal note, ingress means in this case "input", we learn words every day.
# Drop all non-fragmented packets
ip frag-off & 0x1fff != 0 counter drop
# Drop XMAS packets (why involve santa ?)
tcp flags & (fin|syn|rst|psh|ack|urg) == fin|syn|rst|psh|ack|urg counter drop
# Drop NULL packets.
tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop
# Drop uncommon MSS values.
tcp flags syn tcp option maxseg size 1-535 counter drop
}
}
# Define the inet table, responsible for IPv4 & IPv6 incoming and outcoming trafic (inet family) that is coming from outside, but
# also goes outside
table inet filter {
chain input { # Define the input chain, all input in the system for inet (IPv4 + IPv6)
type filter hook input priority 200; policy drop; # Define a hook filter with a priority of 200, by default drop everything
counter jump input_hook # Count packets that was jumped into input_hook (defined below)
counter jump base_filter # Count packets that was jumped into base_filter (defined below)
log prefix "Dropped input traffic: " counter drop # Log the number of dropped packets, in log it'll be prefixed with:
# "Dropped input traffic: "
}
# Define the chain input_hook, empty for now
chain input_hook {
}
chain base_filter { # Define the chain base_filter for all input packets in the system, jumped from base_filter
counter jump drop_filter # Count packets that was jumped into drop_filter (defined below)
ct state vmap { # Accept packets in established and related state
established: accept, # Accept them
related: accept, # Accept them
new: continue, # Continue the filtering for new packets
invalid: drop # Drop everything else, they are invalid
}
# Allow loopback traffic (otherwise, it's a mess, right ? ;])
iifname lo counter accept
oifname lo counter accept
}
# Define the chain drop_filter, empty for now
chain drop_filter {
}
# Define the forward chain for all forwarded packets in the system
chain forward {
type filter hook forward priority 200; policy drop; # Define a hook filter with a priority of 200, by default drop everything
counter jump forward_hook # Count packets that get jumped to forward_hook below
counter jump base_filter # Count packets that get jumper to base_filter above
log prefix "Dropped forwarded traffic: " counter drop # Log the number of dropper packets, in log it'll be prefixed with:
# "Dropped forwarded traffic: "
}
# Define the forward_hook chain, empty for now
chain forward_hook {
}
# Define the output chain and it's rules
chain output {
type filter hook output priority 200, policy drop; # Define a hook filter for output, with a priority of 200, drop everything
# by default
counter jump output_hook # Count packets that get jumped to output_hook
counter jump base_filter # Count packets that get jumper to base_filter
log prefix "Dropped output traffic: " counter drop # Log the number of dropper packets, in logs it'll be prefixed with:
# "Dropped output traffic :"
}
# Define the chain output_hook, empty for now
chain output_hook {
}
}
# Here it takes cares of Network Address Translation for IPv4 & IPv6
# Define the table nat for inet family (IPv4 and IPv6)
table inet nat {
# Define a chain called prerouting
chain prerouting {
type nat hook prerouting priority 0; # Define a hook for prerouting packets, with a priority of 0
}
chain postrouting { # Define a hook for postrouting, with a priority of 500
type nat hook postrouting priority 500;
}
}
# Include anythings that is in /etc/nftables.rules.d and having .rules extensions, based all table, chains and hook above in this file
# That's were the rules are created and state what they will do for each packets (input, output, forwarded, etc).
include "/etc/nftables.rules.d/*.rules"
|
Regards,
GASPARD DE RENEFORT Kévin _________________ Traduction wiki, pour praticiper.
Custom logos/biz card/website. |
|
Back to top |
|
|
nicop Tux's lil' helper
Joined: 10 Apr 2014 Posts: 88
|
Posted: Tue May 14, 2024 12:28 pm Post subject: |
|
|
Hi,
Several comments :
why not default values for priorities ? : https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks#Priority_within_hook
netdev/chain ingress_filter :
if you really want an "ingress" hook, you have to specify the ingress hook and a device (cf nftables : the ingress hook is attached to a particular network interface. )
example : type filter hook ingress devices = { ethX, ethY }
inet/base_filter :
It's counter intuitive to put an output rule (oifname lo) in a chain that will also be applied in an input hook.
iifname/oifname is useless for lo because it's always the first created. iif lo/oif lo are preferred.
The suffix "name" is useful for dynamics interfaces : ppp, vpn ...
inet/output :
you'll get trouble with a drop policy with the output hook. Otherwise, a very long list of exceptions will be required. |
|
Back to top |
|
|
kgdrenefort Guru
Joined: 19 Sep 2023 Posts: 312 Location: Somewhere in the 77
|
Posted: Tue May 14, 2024 1:35 pm Post subject: |
|
|
Hello,
This is from this link from the Gentoo's wiki: https://wiki.gentoo.org/wiki/Nftables#Modular_Ruleset_Management
Since I'm not in ease on this subject, I try to not start from scratch, but at the same time I try to figure out what's going on into that file.
This is my exact needs, but in the big lines:
- Block everything (of course) that is incoming.
- Allow useful stuff as ICMP tho, the good way, not just blocking it blindly.
- Allow only a few ports for the needed services, that would be mostly: 80/443 & 22 a few weeks a year only, maybe allowing a few peoples to access SSH for sFTP file uploading and retrieving. That'll be protected with SSH key no matter what, with a password and I'll filter and only allow some IPs for that matters.
- In the end, only allow what is needed for a server acting also as a workstation, I can't blindly drop/reject every output, I still have to be able to use my server/workstation .
For default values priorities, I still do not understand yet how it could be important, simply it allows some traffic to get taken care of before other, I guess ?
For ingress, I'm not quite sure what it does actually.
From the netfilter wiki:
Code: | The ingress hook was added in Linux kernel 4.2. Unlike the other netfilter hooks, the ingress hook is attached to a particular network interface.
You can use nftables with the ingress hook to enforce very early filtering policies that take effect even before prerouting. Do note that at this very early stage, fragmented datagrams have not yet been reassembled. So, for example, matching ip saddr and daddr works for all ip packets, but matching L4 headers like udp dport works only for unfragmented packets, or the first fragment.
The ingress hook provides an alternative to tc ingress filtering. You still need tc for traffic shaping/queue management. |
So, ingress is only attached to a network interfaces, taking care of some extra stuff before it is taken care of by other filter/hook ? I guess it allows to have NFTables takes care of less «useless» or undesired packets ?
About inet/base_filter, if you are right, the wiki deserve an update about it. If you are true, I could take care of reporting that to the good persons.
So, from what you say, this is not a good configuration to keep going ?
Regards,
GASPARD DE RENEFORT Kévin _________________ Traduction wiki, pour praticiper.
Custom logos/biz card/website. |
|
Back to top |
|
|
nicop Tux's lil' helper
Joined: 10 Apr 2014 Posts: 88
|
Posted: Tue May 14, 2024 3:06 pm Post subject: |
|
|
Okay. I didn’t have that reference. That explains and invalidates some of my comments (priorities, ingress without device).
kgdrenefort wrote: | Since I'm not in ease on this subject, I try to not start from scratch, but at the same time I try to figure out what's going on into that file. |
Modular management is more complex and, in my opinion, is only required for advanced needs. Otherwise, it affects understanding.
This example appears to be a way to make starting easier and meets your requirements : Nftables/Examples
Modularity will then be implemented, according to your needs.
kgdrenefort wrote: | So, ingress is only attached to a network interfaces, taking care of some extra stuff before it is taken care of by other filter/hook ? |
Yes. So, dropping with that hook "should" be faster. I don't think it matters for domestic fiber.
kgdrenefort wrote: | For default values priorities, I still do not understand yet how it could be important, simply it allows some traffic to get taken care of before other, I guess ? |
Chains from the same hook are the only ones affected by priority. The sequence of chains could have a significant effect. An accept rule is always temporary, while a drop rule is effective immediately.
Example : https://stackoverflow.com/a/64977634
kgdrenefort wrote: | About inet/base_filter, if you are right, the wiki deserve an update about it. If you are true, I could take care of reporting that to the good persons. |
It’s just a comment for understanding. It has no real impact. |
|
Back to top |
|
|
kgdrenefort Guru
Joined: 19 Sep 2023 Posts: 312 Location: Somewhere in the 77
|
Posted: Wed May 15, 2024 11:42 am Post subject: |
|
|
Hello and thanks for your reply.
So, I simply added a very few comments to the code below:
Code: | #!/sbin/nft -f
# Drop every existing rules, chains, tables and hooks.
flush ruleset
# Define the table for inet families (IPv4 + IPv6)
table inet filter {
# Define the input chain
chain input {
type filter hook input priority 0; policy drop; # Define a hook filter for input with priority 0, drop everything else
ct state invalid counter drop comment "early drop of invalid packets"
ct state {established, related} counter accept comment "accept all connections related to connections made by us"
iif lo accept comment "accept loopback"
iif != lo ip daddr 127.0.0.1/8 counter drop comment "drop connections to loopback not coming from loopback"
iif != lo ip6 daddr ::1/128 counter drop comment "drop connections to loopback not coming from loopback"
ip protocol icmp counter accept comment "accept all ICMP types"
meta l4proto ipv6-icmp counter accept comment "accept all ICMP types"
tcp dport 22 counter accept comment "accept SSH"
counter comment "count dropped packets"
}
# Define the chain for forwarding
chain forward {
type filter hook forward priority 0; policy drop; # Define a hook filter for forwarded packets with a priority of 0, drop everything else
counter comment "count dropped packets"
}
# If you're not counting packets, this chain can be omitted.
# Define the output chain
chain output {
type filter hook output priority 0; policy accept; # Define the filter hook for output packets, priority 0, accept everything
counter comment "count accepted packets"
}
} |
So far as I understand, for now, this file does almost nothing:
1/ It drops every existing rules (flush ruleset), we start from nothing.
2/ Define the main table, the only one for now, for the inet family (so it is managing IPv4 & IPv6 as well)
3/ Inside the main table, it defines 3 chains:
3/ a) One for input (everything that try to come in, as loopback so everything incoming from my system but also not leaving it either), reject everything trying to use loopback but not incoming from my system and accept ICMP as SSH on port 22. Count the dropped packets too.
3/ b) One for forwarded packets, if it's not for forwarding it is dropped by default, count the dropped packets too.
3/ c) It merely allow everything to goes out, but allow me to count it if I feel like it.
So, if today I wanted to setup a very simple firewall, I could only use this file and add, for example, a few rules into the chain input for such services:
Code: |
tcp dport 22 counter accept comment "accept SSH"
tcp dport 80 counter accept comment "accept HTTP"
tcp dport 443 counter accept comment "accept HTTPS"
|
This will allow for example to host a webserver, running on usual port for HTTP/HTTPS and allows me to connect from SSH:
Code: | #!/sbin/nft -f
# Drop every existing rules, chains, tables and hooks.
flush ruleset
# Define the table for inet families (IPv4 + IPv6)
table inet filter {
# Define the input chain
chain input {
type filter hook input priority 0; policy drop; # Define a hook filter for input with priority 0, drop everything else
ct state invalid counter drop comment "early drop of invalid packets"
ct state {established, related} counter accept comment "accept all connections related to connections made by us"
iif lo accept comment "accept loopback"
iif != lo ip daddr 127.0.0.1/8 counter drop comment "drop connections to loopback not coming from loopback"
iif != lo ip6 daddr ::1/128 counter drop comment "drop connections to loopback not coming from loopback"
ip protocol icmp counter accept comment "accept all ICMP types"
meta l4proto ipv6-icmp counter accept comment "accept all ICMP types"
tcp dport 22 counter accept comment "accept SSH"
tcp dport 80 counter accept comment "accept HTTP"
tcp dport 443 counter accept comment "accept HTTPS"
counter comment "count dropped packets"
}
# Define the chain for forwarding
chain forward {
type filter hook forward priority 0; policy drop; # Define a hook filter for forwarded packets with a priority of 0, drop everything else
counter comment "count dropped packets"
}
# If you're not counting packets, this chain can be omitted.
# Define the output chain
chain output {
type filter hook output priority 0; policy accept; # Define the filter hook for output packets, priority 0, accept everything
counter comment "count accepted packets"
}
} |
This settings should be fine, I guess, for a non-professional self-hosted server, acting as a workstation too. What do you think ? Is it OK to start from that ?
Later I'll need to open other services, in my pipe I had to add a Minetest server, it usually use port 30000 (UDP), so I should add this rule:
Code: | udp dport 30000 counter accept comment "accept Minetest" |
Then peoples would be able to connect from LAN or Internet to this server.
What do you think ?
Regards,
GASPARD DE RENEFORT Kévin _________________ Traduction wiki, pour praticiper.
Custom logos/biz card/website. |
|
Back to top |
|
|
nicop Tux's lil' helper
Joined: 10 Apr 2014 Posts: 88
|
Posted: Wed May 15, 2024 12:23 pm Post subject: |
|
|
kgdrenefort wrote: | So, if today I wanted to setup a very simple firewall, I could only use this file |
Yes.
kgdrenefort wrote: | and add, for example, a few rules into the chain input for such services:
tcp dport 22 counter accept comment "accept SSH"
tcp dport 80 counter accept comment "accept HTTP"
tcp dport 443 counter accept comment "accept HTTPS"
|
Yes.
kgdrenefort wrote: | This settings should be fine, I guess, for a non-professional self-hosted server, acting as a workstation too. What do you think ? Is it OK to start from that ? |
Yes. Check the SSH configuration before opening port 22.
At the beginning, you should too log dropped packets :
Quote: | log prefix "fw input denied : " counter comment "count dropped packets" |
kgdrenefort wrote: | udp dport 30000 counter accept comment "accept Minetest" |
Yes.
kgdrenefort wrote: | What do you think ? |
Let's go. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|