While they are many available firewall for Linux, none of them are really designed for virtualization. Obviously it is alway possible to hack an existing one to fit your need, but VM-firewall has been designed to support virtualization in a Internet hosted environment, it runs the same rules for Xen, OpenVZ and VirtualBox. The goal of VM-Firewall if to provide to virtualization administrator the same facility has the one provided by an intelligent router in a traditional architecture, it is particularly useful for people who have multiple IP addresses that they want to forward on different virtual machines.
Disclaimer
| Table of Contend |
Architecture
When running virtualization in a hosting environment, the main issue is the lack of access to networking infrastructure. Usually you get access to a limited number of public IP, with no DHCP and/or ARPA facilities. This imposes your virtualization infrastructure to be completely invisible from your provider's router. For this reason VM-firewall does not expose virtual machines directly to physical interface, but leverages virtual network interfaces, iptables and routing capabilities to map data stream to a given VM.
- For input initiated stream: VM-firewall maps an external IP+port to a given destination VM+port. VM receives the original Internet source IP addresses and can very easily applies their own network access control. Note: one given VM may received internet stream from more than one external IP addr (which does not mean it is a good idea)
- For output initiated stream: VM-firewall groups VM into zones, Then based on zones internal IP addresses and attached virtual network interface, it reverses map VM's internal IP to chosen external IP address. Outgoing stream are handle through a simple NAP operation, the only difference with a simple NAT as your home aDSL modem/router is that depending on the selected zone, your parquet will appear as coming from a different public IP. Note that as external public IP address selection is based on zone local network internal IP+virtual-NIC, for a given VM, outgoing stream can only NAT one public IP addr.

VM-Firewall uses 3 class of objets.
- zones: virtual machines are grouped into zones. A configuration have two or more zones: a dummy one named "none" for the hypervisor, and one to many for virtual machines. Typically the number of zones is equivalent to the number of external IP addresses+1(for hypervisor). Each zone may contend one to many virtual machines. zone is a set of virtual machines that shared a unique:
- virtual network interface
- local virtual network mask
- external IP address
- application: inside a zone it defines a port-forwarding for external data stream to internal virtual machines. An application takes as input a port and as destination a virtual machine's virtual network's IP+port.
- tuning: optional values that allow you to enforce some global policies at zone level. Tuning may be used to prevent a zone to send SMTP traffic, or to limit SSH access from a given network, etc.
Configuration
Introduction
Config file can either be a flat file or a directory containing one to many *.conf rules. VM-firewall uses a two passes architecture: first pass reads every config files and loads them into tables, second pass scans those tables and generates iptables rules. This two pass model provides a lot of flexibility to configuration syntax, it:
- decorelates configuration syntax from iptables structure
- validates configuration independently of file order
- generates easy to read/understand iptables rules
- allow a lot of debugging tools

Zones
In a traditional ISP zones defines a group of servers attached to a specific VLAN. Real ISP typically have 5 to 10 zones [ex: common services, database, messaging, etc]. Many of us should be more than happy with one or two zones. If you have two external IP addresses you may want two zones, this because nating for outgoing traffic is attached a given zone. For each zone we must define:
- The external NIC (required is your zone host Internet application)
- The external IP address (one NIC support many IP)
- The internal virtual interface (your bridge for: Xen, vmWare, virtualbox and vnet for OpenVZ)
- The Internal IP address. (traffic for the zone is routed through this interface)
| # Example of rules to create Tree Zones# ----------------------------------------------------------- CreateZone NAME=WEB NIC=eth0 EXT=91.121.65.xx BR=vnet-br INT=10.10.1.1 MASK=255.255.255.0 CreateZone NAME=Messaging NIC=eth0 EXT=87.98.130.xx BR=vnet-br INT=10.10.2.1 MASK=255.255.255.0 CreateZone NAME=Admin NIC=none EXT=none BR=vnet-br INT=10.10.3.1 MASK=255.255.255.0 |
Normally a zone is connected to Internet through a public IP, nevertheless you may want to have an "admin" zone dedicated to internal services (ex: DHCP, LDAP, Backup, ...) that you isolate from Internet. A zone receives traffic from:
- Incomming Internet traffic is DNAT to the internal IP/Port providing the service
- Outgoing Internet traffic is NAT to appear as coming from your external IP
- VPN is fully routed within the admin network
Default behaviour
- not to accept any traffic from Internet
- allow any traffic from the VM to the outside
- Internal and VPN traffic are unlimited in both direction.
Note: zones do not define security inside your VM. If needed each VM can define it own access rules (firewall, apache acl, ...). Security provided by your zone is more or less equivalent of LAN and port locking as provided by intelligent switch/routers (Alteon, Cisco, ...)
Application
As said previously default zone behavior is to lock any traffic from Internet. When hosting applications you want some Internet traffic to be routed from the external NIC to your VMs. For each given application, WM-firewall is doing tree things:
- open given port/proto on external interface for the given IP (in case you have more than one IP on your NIC)
- forward incoming traffic to the internal VM using DNAT functionality
- NAT outgoing traffic to to hide your Internal VM IP addr make it appear as coming from a public IP address.
| # Example of 5 applications rule, sitting in our tree previsouly created zones # ------------------------------------------------------------------------------------------ CreateApp NAME=SMTP ZONE=Messaging EXT=tcp:25 INT=10.10.1.2:25 CreateApp NAME=WEBMAIL ZONE=Messaging EXT=tcp:80 INT=10.10.1.3:80 CreateApp NAME=PORTAL ZONE=Web EXT=tcp:80 INT=10.10.2.2:8080 CreateApp NAME=PBX ZONE=Messaging EXT=udp:5600 INT=10.10.3.3:5600 CreateApp NAME=PRIVATEIP ZONE=PRIVAT_IP EXT=tcp:any INT=10.10.4.3:any |
For each application we have to provide
- NAME a Label that should be unique in each file,
- ZONE this is zone as defined previously, it will define you external IP address and your internal netmask.
- EXT the external port/proto your application is listening. Be careful not to overlap your listening port, this especially when two zones are using the same external IP address.
- INT your internal IP address and port, as obviously nothing force you to present the same port internally and externally.
Tuning
Optional zone access control parameters, that most of you will probably ignore, expect if you're realy sure you need it, start without. Nevertheless they are cases where not only you want to control external traffic, but you also want to control internal traffic. For example let's say that one of your zone is used by student for admin security labs, while some others are used for real "in production" university applications. You may want to restrict SSH access even from the internal LAN/VPN to your "in production zone". Equally, you may want to forbid peer to peer or SMTP outgoing from some zones. Tuning is important as soon as you cannot trust the admin of a given virtual machine, this even if this guy has root passwd for his own VM or even the full set of VM in a given zone. You as the hypervisor admin want to make sure than what ever any VM admin is doing you keep control or the global platform.
| # Zone tuning (internal and outging traffic control)# --------------------------------------------------------------- # Prevent Zb to send mail TuneZone NAME=ZA_SMTP_NO ZONE=ZA DIR=out ACTION=drop PORT=tcp:25 # Limit Zb SSH access to VPN subnet 10.10.11.0/255.255.255.0 TuneZone NAME=ZB_SSH_LIMIT ZONE=ZC DIR=in ACTION=accept PORT=tcp:22 src=10.10.11.0/8 # Only allow SSH and openVPN access to Zc TuneZone NAME=ZC_SSH_OK ZONE=ZC DIR=in ACTION=accept PORT=tcp:22 TuneZone NAME=ZC_VPN_OK ZONE=ZC DIR=in ACTION=accept PORT=udp:1194 TuneZone NAME=ZC_ANY_NO ZONE=ZC DIR=in ACTION=drop PORT=tcp:any |
Tuning applies in between opening application port and closing iptables chain of a given zone, this to assert that default action for incoming packets is "drop". Tuning iptable are applyied directly on zone Internal interface (ex: Xen Bridge, OpenVZ vnet) and can thus lock any traffic before it get the chance of behing evaluated for routing. You can use tuning rules to limit incoming/outgoing traffic, rules will affect both external an internal LAN.
Command line syntax
The parser is only a very basic shell script, and while my goal was to make the config file as simple as possible I did not spend much time in tracking lexical/grammatical errors. For this reason before going in production you MUST check that both you and my parser have the same understanding of your rules. This is especially important if you run a remote machine as locking your external interface may prevent you from accessing to your machine. General syntax is "Fridu-firewall.script command option-1=xxx ... option-n=..."
The parser will first read all your rules and then depending on your command will generate the adequate iptables.
- Fridu-firewall.script display ;# config as understood by parser [should be used after each rules update]
- Fridu-firewall.script test ;# start firewall and stop it automatically after 180s
- Fridu-firewall.script start ;# build iptables and activate firewall
- Fridu-firewall.script stop ;# delete every zone table and leave all your ports open with routing active
- options:
- config=file|directory ;# overwrite default config
- debug=1 ;# only design to debug the script
- verbose=1 ;# step by step verbose mode
- dummy=1 ;# generate rules but do not apply them
- dump=file ;# dump the iptable to a file
- ex: Fridu-firewall.script start dump=/tmp/my-iptables [Start firewall and dump a copy of rules in /tmp/my-iptables]
- ex: Fridu-firewall display config=/etc/sysconfig/Fridu-firewall/samples/Fridu-firewall-Guru.config
Action section
This is optional, and hopefully most of you wont need it
Action section is not handle directly by VM-firewall script, it is only a convenient place for addon functions, you would like to start with firewall boot from /etc/init.d time, as:
- bridge creation
- special rules to allow one zones to talk to the other
- allow VPN traffic
- etc.
Any shell command can be used, action is either "start" or "start", as stopping a firewall before shutting down a machine is quite useless, is a special action is needed most of you should only implement the "start" part of it.
Example-XEN:
Warning: In order to use VM-firewall with Xen you need to update Xen's network script, check full article [here]
- allow VPN(tun+) to/from traffic to zone(xen-br+)
- allow zones to zones traffic ( -i xen-br+ -o xen-br)
| if test "$ACTION" = "start" ; then DoIt iptables -A after-forwarding -i xen-br+ -o xen-br+ -j ACCEPT # allow VM to talk together DoIt iptables -A after-forwarding -i tun+ -o xen-br+ -j ACCEPT # allow VPN talk to zones DoIt iptables -A after-input -i tun+ -j ACCEPT # allow VPN talk to dom0 DoIt iptables -A after-forwarding -i xen-br+ -o tun+ -j ACCEPT # allow Zones talk to VPN fi |
Example-OpenVZ:
For further information check OpenVZ-Proxmox and VM-firewall post [here]
- allow to/from VPN traffic(tun+) to zones virtual interface (vnet+)
- allow zones to zones traffic (-i venet+ -o venet+)
- hack to map IP-two ssl port to internal 563 openvpn TCP port (this because SSL on IP-one is used for web applications)
| # User Before/After Zone Custom Tables (before-input|output|forwarding, after-input|...) # ---------------------------------------------------------------------------------- if test "$ACTION" = "start" ; then # DoIt modprobe -s ip_conntrack_ftp # load FTP session tacking # we're not a bank make our life simple DoIt iptables -A after-forwarding -i venet+ -o venet+ -j ACCEPT # allow VM to talk together DoIt iptables -A after-input -i tun+ -j ACCEPT # allow VPN talk to dom0 DoIt iptables -A after-forwarding -i tun+ -o venet+ -j ACCEPT # allow VPN talk to zones DoIt iptables -A after-forwarding -i venet+ -o tun+ -j ACCEPT # allow Zones talk to VPN # Make SSL on IP-two to be redirected on port 563 DoIt iptables -A PREROUTING -t nat -i eth0 --destination 87.98.139.141 --proto tcp --dport 443 -j DNAT --to 91.121.173.80:563 fi |
Example VirtualBox
For further information on VirtualBox and VM-firewall check [here]
- create a bridge for virtual box and map local virtual address onto it
- create a Tun network interface for each virtual machine and add them into the bridge
- at stop time delete the bridge [just to prove it works :)]
if test "$ACTION" = "start" ; then # which use own virtualbox bridge VBOX_USER=fulup # zoneONE bridge and tap brctl addbr vbox-br1 2>/dev/null ifconfig vbox-br1 $IP_BR1 netmask 255.255.255.0 for VBOX in vbox12 vbox13 do VBoxTunctl -u $VBOX_USER -t $VBOX ifconfig $VBOX up brctl addif vbox-br1 $VBOX done fi if test "$ACTION" = "stop" ; then # remove bridge brctl delbr vbox-br1 fi |
QuickStart & Debug
Sample config and debug explanation are locate on a dedicated page [here]Bugs/Limits
Parser is bash based and very primitive.It is very sensitive to "strings", especially labels/names of rules must be in pure basic alphanumeric characters. This is because parser build a shell variable with each label, which explain why label are so restrictive. As a result "MyZone or MY_Zone" is OK when "My-Zone or My:Zone" is not.
When using shared shell variables (ex: for PUBLIC-IP, Virtual-Interface names, ...) make sure that your "1st-defintion.conf" configuration file owning those variables is readed before the config using it [*.conf are readed is alphabetic order] In case of doubt use "Fridu-firewall start dummy=1 verbose=1 dump=/tmp/iptables" verify that the file owning shared variables definition is readed 1st, and if needed "vi /tmp/iptables" to verify that variables where effectivly expended.
Download installation
FW-firewall is written on bash shell, and should work out of box on any Linux distribution. After download the easiest way of to copy a sample config that is close of yours, to copy it in a private directory and then to customize it to your need. This behind done, You can install VM-firewall and select your own rules as default config.
- Downloaded VM-firewall from (here)
- (cd /opt; tar -xzf VM-Firewall-*.tgz)
- cd /opt/VM-Firewall
- cp ./fw-rules/ChoosenTemplate ./fw-rules/my-$HOSTNAME
- ./install template=my-$HOSTNAME
- edit config in ./fw-rules/my-$HOSTNAME
- Fridu-firestart display
- Fridu-firewall test timeout=180
- Fridu-firewall start
Note:
- installation does not copy files, but link distribution to well know location (/usr/sbin for commands and /etc/default | /etc/sysconfig for configurations). As a result "/opt/VM-Firewall" should not be deleted after installation, and building your config in /opt/FW-firewall/fw-rules or in /etc/sysconfig/Fridu-firewall is equivalent.
- Autoboot: a startup script is placed in /etc/init.d and activate firewall at boot time. Two init.rc templates are provided one for Debian, the other one for SLE.
- Default config: is defined by FWCONFIG=xxxx in either /etc/default/Fridu-default (debian,ubuntu) or /etc/sysconfig/Fridu-default (opensuse, redhat, ...). FWCONFIG should point on a template directory inside "fw-rules" directory. You can overload default value with "config=xxx" option, nevertheless init.d only start default configuration. Note that install.sh will set default template, if specifyed at installation time. To control/verify your default config use: "Fridu.firewall display"
Example of display command





Voici ce que j'ai rajouté dans tunning:
- DoIt modprobe -s nf_nat_ftp
- DoIt modprobe -s nf_conntrack_ftp
Ensuite j'ai lancé ceci:
- rmmod nf_nat_ftp; rmmod nf_conntrack_ftp;Fridu-firewall start
lsmod me retourne sa maintenant:
- root@ns211308:/# lsmod
- Module Size Used by
- nf_nat_ftp 12416 0
- nf_conntrack_ftp 19496 1 nf_nat_ftp
La connection ftp fonctione.
David.
==> Réponse Fulup
Un grand merci à David, je suis certain que sa contrib, intéressera effectivement du monde. A noter que la commande rmmod des modules ne sert à rien, mais sinon c'est tout bon.
Tout d'abord merci pour ce tutoriel très complet sur la Virtualisation.
J'ai toutefois une petite question au sujet des plage de ports.
En effet, j'ai un serveur vsftpd en mode passif qui utilise les ports 40000 à 40100 pour la connection data.
J'ai essayé de créer une règle dans tuning.conf en suivant l'exemple que vous aviez donné à Trevor pour SIP, mais rien n'y fait.
règle rajoutée :
DoIt iptables -A zFour-input -i eth0 --proto tcp --dport 40000:40100 -j ACCEPT
DoIt iptables -t nat -A zFour-prerouting -i eth0 --destination --proto tcp --dport 40000-40100 -j DNAT --to 10.10.15.10
Le problème, c'est qu'au redémarrage du script, iptables renvoie des erreurs
iptables: No chain/target/match by that name
-- ERR iptables -A zFour-input -i eth0 --proto tcp --dport 40000:40100 -j ACCEPT
-- ERR iptables -t nat -A zFour-prerouting -i eth0 --destination 87-98-133-187 --proto tcp --dport 40000-40100 -j DNAT --to 10.10.15.10
Après plusieurs tests,debug...etc j'ai remarqué que les lignes de tuning.conf sont générées en premier donc je comprend le premier message d'erreur.
-> modification du script Fridu-Firewall script pour generer les lignes suivantes
iptables -A zFour-input -i eth0 --proto tcp --dport 40000:40100 -j ACCEPT
iptables -t nat -A zFour-prerouting -i eth0 --destination 87-98-133-187 --proto tcp --dport 40000:40100 -j DNAT --to 10.10.15.10:40000-40100
Malheureusement, rien n'y fait...
Pourriez-vous svp m'éclirer sur le sujet?
Merci par avance
==> Réponse Fulup
La réponse est dans ton texte, les commande DoIt sont des IPTABLES de bases. Il faut donc utiliser les zones standard de Linux after-input, after-forwarding,PREROUTING, FORWARD,POSTROUTING,...
sa a l'air de bien fonctionner chez moi mais le firewall ne demare pas quand je reboot la machine
et je suis obligé de le redemarer avec la commnade Fridu-firewall start pour que mes vps
redeviennent visible sur la toile.
j'ai essaye : update-rc.d Fridu-firewall defaults
mais il me retourne : System startup links for /etc/init.d/Fridu-firewall already exist.
si vous pouviez m'aider.
merci d'avance.
== Réponse Fulup
Si le lien existe, c'est que ce n'est pas la première installation, tu peux donc ignorer le warning. Par contre si le Firewall ne démarre pas en automatique au boot, c'est que ma config autostart ne fonctionne pas avec ta distrib (pas forcément surprenant, car je ne reboot jamais ma machine). Pour un démarage au boot, ce qu'il faut c'est que la commande "/etc/init.d/Fridu-firewall start" soit exécuté après la mise en place de la carte réseau. Il suffit donc de l'ajouter quelque part dans un de tes scripts de démarage.
===> Fulup Respond
Probably just because I'm too lasy :)
More seriously, VM-firewall is only a smart script with less than 1000 lines of bash code. It's now in production since 2007 and it's pretty stable. In the past years, only one person proposed lines some code for improvement. This being said if someone wanted to work on it for extensions, I'm not opposed to push the code on sourceforge or others.
I am now running openvz template pbxinaflash, my phones are functioning they all can make sip and landlines calls and recieve sip calls however there is no voice. I am thinking its a port range issue.
Is there a way in VM-firewall to forward port ranges for the host in a particular zone. All my other ports are correctly working. Is there a delimiting character to specify the range From - To.
Thanks
====> Fulup Respond
PBXinAflash is based on Asterisk, you need to update your /etc/asterisk/rtp.conf to force the range of RTP ports (cf: rtpstart/rtpstop) (http://www.fridu.org/asterisk-pbx-faqs-tips-78/38-5-asterisk-sip-media-nat). SIP's signalization goes through UDP port 5060 and follow proxy chain, but media stream (voice/video) follow a more direct link, and RTP streams try to bypass proxies to establish if possible a direct link in between sender/receiver handset. In the ideal scenario, your media stream should not even touch your PBX, but in case your PBX acts as an intermediary for both SIP(signalization) and RTP(media). Then you need to force RTP range redirection directly toward your VM in tuning.conf. Example here after
# special SIP rules to accept RTP port range from 7070 to 7090
DoIt iptables -A zOne-input -i eth0 --proto udp --dport 7070:7090 -j ACCEPT
DoIt iptables -t nat -A zOne-prerouting -i eth0 --destination MY-PBX-PUBLIC-IP --proto udp --dport 7070-7090 -j DNAT --to MY-VM-PBX-IP
Note that RTP stream are some how challenging to configure correctly, you may find some resource on Fridu:
http://www.fridu.org/asterisk-pbx-faqs-tips-78/36-4-asterisk-sip-signalling-nat
http://www.fridu.org/sip-voiceip-faqs-tips-83/42-siemens-s450
This without ignoring Qos which is a "MUST HAVE" feature, in order to get good voice quality http://www.fridu.org/hosting/51-network-qos
Last but not least when all of this will work, you may want to read the last paper I produce on the future of SIP: http://www.fridu.org/fulup-publications :)
Fulup
J'utilise votre solution sur openVZ. Je souhaite utilisé un serveur FTP. Pour cela, j'ai décommenté la ligne suivante dans tuning.conf : DoIt modprobe -s ip_conntrack_ftp
Pour une raison que j'ignore, j'ai une erreur au redémarrage du FW :
-- ERR modprobe -s ip_conntrack_ftp
Avez-vous une idée ? En vous remerciant
===> Fulup respond
This mean that when the firewall try to upload ftp module modprobe return an error. You should make sure that ip_conntrack_ftp is installed on your distribution. Did you check by hand "modprobe -s ip_conntrack_ftp"
Tu indiques qu'il est fortement recommandé d'utiliser venet interface à la place de veth pour le couple openvz fridu-fw. J'ai absolument besoin d'avoir une adresse MAC sur ma VM, j'ai donc 2 solutions : soit créer une interface virtuelle dans la VM (je ne sais pas faire) soit utiliser veth.
Sachant que l'adressage IP sera privé, quels sont les raisons qui poussent cette recommandation ?
Cordialement,
Matt
===> Réponse Fulup ===
Effectivement l'interface VETH est intéressante dans un environnement de développement ou, chaque VZ fait une requette DHCP pour obtenir une adresse IP, ce qui veut dire que le protocole ARPA est utilise N fois la même adresse MAC (une fois par adresses IP). Dans un environnement hosté type OVH ou autre, l'aliasing de N adresses IP pour une adresse MAC est interdit. Ceci pour être certain qu'un serveur ne vole pas les adresses IP d'un autre, du coup le protocole ARPA est limité à une adresse IP par adresse MAC. Au final toutes nos adresse IP dite secondaires, sont en fait de simple forward au niveau du switch/router. Ceci explique cela.
Pour une VM spécifique, j'ai attribué une IP Publique. Elle est parfaitement joignable de l'extérieur. Je souhaiterais malgré tout sécurisé les accès via VM-firewall. Est-ce possible ? Si oui, je ne vois pas comment déclarer la zone .. dois-je utiliser tuning ?
Merci d'avance
Matt
=====> Fulup Respond ====
En fait attribuer une IP publique à une VM, correspond de fait à rediriger tous les ports ciblant cette IP vers la VM en question. Au final c'est toujours l'hyperviseur qui reçoit les paquets. L'idée d'attribuer une IP à une VM reste très virtuelle:)
Pour protéger une VM tout en lui affectant une IP privée, il suffit de faire une zone pour l'IP en question. Puis de mapper les applications avec "CreatApp" dans la zone en question avec comme destination la VM cible. Seuls les ports déclarés dans des fonctions "CreatApp" seront redirigés les autres seront bloqués au niveau de l'hyperviseur.
Thanks a lot for it's working really fine for me. but I got a question.
I have 2 servers with proxmox 1.3. Both are setup with VM-Firewall with an internal network 10.0.0.0. All VMs can talk to the internet and can talk to the local VMs. (Both servers are in a cluster config)
What I want to acheive is VMs on node 1 to talk to VMs on node 2 (they are the same network 10.0.0.0)
Dietmar from proxmox tells me that I should not masquerade when destination is 10.0.0.0 for it to work.
How should I set that up ?
Thanks for your help.
===>Fulup respond ===
I do not use cluster yet [I only have one server :)], but I see at least two options:
*1) You change for two internal network ex: 10.10.1.x et 10.10.2.x
--you have OpenVPN install and you pass through OpenVPN to talk from one any VM to any VM ignoring cluster.
--you add an special routing from one hypervisor to the other one.
*2) you must keep internal IP in the same network for cluster reason (moving one VM from one cluster to an other one keeping the same internal IP)
-- one option is to use openvpn in bridge mode; but this impose one openvpn per VM. Note that in this case you may chose to run OpenVPN as a simple tuner without any chrypto/authentication in order to make it faster.
-- you may also choose two IP for each VM, one independant of the localisation, the other one not.
Comment intégrer des règles intégrant le protocol GRE au sein du Firewall ?
J'ai essayé sans succès.
Merci d'avance
=== Fulup respond ===
Je n'utilise pas le VPN M$, ce qui explique que je n'ai pas de regle pour le protocol GRE(47)
Ceci dit en ajouter dans le fichier "tuning.conf la regle suivante
"DoIt iptables -A after-input -p 47 -j ACCEPT" alors les paquets GRE vont pouvoir rentrer.
J'ai essayé une installation sur un environnement Centos 5.3 auquel j'ai greffé un noyau patché openvz, tout marche à merveille. J'y ai rajouté le VM-Firewall et j'ai configuré ce dernier. L'accès et la configuration réseau de mes VM et simplifiées.
Cependant, j'aimerais, pour des questions de tests, ouvrir entièrement l'hyperviseur niveau port. J'ai alors essayé de mettre la balise any dans le fichier de conf, mais il ne me l'a prend pas, j'ai passé la balise * all et même rien, et pareil, lors du lancemend du firewall j'ai une erreur comme quoi iptables à générer une erreur.
Une idée? Merci encore une fois
============== Réponse Fulup =============
Il est certain que d'ouvrir tous les ports, même pour un test test une mauvaise idée, mais bon :) Ceci étant dit, Il suffit d'ajouter dans "tuning.conf" une règle iptables qui ouvre tous les ports.
Par exemple pour autoriser le traffic entrant via eth0 d'une DMZ (network 10.10.10.x) et son routage vers les autres interfaces ethernet, on utilisera les règles suivantes:
> DoIt iptables -A after-input -i eth0 -s 10.10.10.0/8 -j ACCEPT # allow any incoming traffic from DMZ
> DoIt iptables -A after-forwarding -i eth0 -s 10.10.10.0/8 -o eth+ -j ACCEPT # allow DMZ routing
Pour autoriser tous le traffic entrant il suffit de suprimer la restriction sur les adresses IP sources "-s 10.10.10.0/8" ainsi que la regle de forwarding, si le traffic n'est qu'a destination de l'hyperviseur.
ATTENTION: même pour un test, ca n'est pas une bonne idée d'autoriser tous le traffics, il faut toujours reduire au maximum le range d'authorisation (par example n'autoriser tous les ports qu'a la machine utilisée pour les tests).
Tout d'abord merci pour ce site et la video de présentation de proxmox, c'est une architecture vraiment tip top.
Je débute aussi bien en linux qu'en virtualisation et j'ai tout compris, je suis donc en train de mettre en place votre architecture sur une machine de test et j'ai un problème depuis le début avec proxmox : mes VMs n'accèdent pas à internet par le biais de l'hyperviseur qui devrait faire son rôle de routeur.
J'ai suivi le wiki de openvz : http://wiki.openvz.org/Using_NAT_for_container_with_private_IPs
mais rien à faire mes VMs ne sortent pas de l'hyperviseur
C'est en cherchant sur le net pour ce problème que je suis tombé sur votre site et du coup j'ai installé votre firewall des fois que des règles sont ajoutées mais apparemment non.
Je précise qu'étant débutant à la base, j'ai installé la version de proxmox fournie sur leur site. (apparemment basé sur une DEBIAN) J'ai eu le même problème que Zenny avec le coup du vmbr0 au lieu de eth0.
Donc je suis coincé sur ce problème des VMs qui ne sortent pas de l'hyperviseur, j'espère que vous pourrez m'éclairer.
Cordialement
Didier
i'm using openVZ on a server from french OVH
but (yes there is two "but" ;-))
1/ on my serveur i have 2 Ethernet card...
all the config i made for IP's on the first eth0 work great !
when i make the same config (change only IP and "NIC=eth1" in the zone.conf) i can connect to ssh for exemple
but a "ping google.com" don't work.
i search, but find anything to explain this...
when i come back (change IP and NIC=eth0) all work....
2/ for a FTP server (vsftpd) in passive mode i must one an Range of Ports 30000 to 30999
is ot possible to do that with fridu-firewall ? and how ??
====== Fulup respond ========
Thank's for the compliment, for your two questions:
1) It works (at least it should): But changing the NIC interface is not enough. NIC is use for incoming packets, for outgoing packets your firewall can only find adequate target public IP address from the internal zone's netmask. If you check with dump option, you will see that for outgoing packets firewall generate this type of rules "iptables -t nat -A zoneX-postrouting -o zone(NIC) --source zone(network/mask) -j SNAT --to zone(public-ip). In your case your zone's netmask has to be wrong
2) I did not integrate any FTP's rules:( it is on my todo list but the priority is not hight enough for me to promise anything. As a result you have to handle FTP by hand, on the other hand if you're willing to create an FTPrule I would be more than happy to integrate it :)
First of all thanks for the great work! I enjoyed studying and learning from your VM-firewall framework.
I've setup VM-firewall and it works great. I've a question about the generated filtering rules. Look at these rules:
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
iptables -A INPUT -j REJECT --reject-with icmp-port-unreachable
iptables -A OUTPUT -j ACCEPT
iptables -A OUTPUT -p tcp -j REJECT --reject-with tcp-reset
iptables -A OUTPUT -j REJECT --reject-with icmp-port-unreachable
Those are generated by VM-firewall. Can you please explain those six lines to me? (they are rendered at the end of the input/output chain)
Kind regards,Murat, The Netherlands
============== Fulup Answer ==================
Those are anti-scan rules, you should find something equivalent on most firewalls, they help fighting basic attacks by limiting your internet visibility to port scanning. First set (--reject-with icmp-port-unreachable) prevent returning a status on close ports, Fridu-firewall just refuses requests. Second one (--reject-with tcp-reset) prevents from returning an "open but protected" status. If necessary you may reduce some more your visibility by adding "-m limit --icmp-type 0 --limit 5/minute" to the "icmp -J ACCEPT". At the end of the day those rules do not impact open ports, they only slow down port scanning. Try an nmap on your system with and without Fridu-firewall, you will see how slow it is to respond when those rules are activated.
# brctl show
bridge name bridge id STP enabled interfaces
vmbr0 8000.MAC_ADDRESS yes eth0
I am stuck somewhere. I have installed the Fridu-firewall (really wonderful, no words to appreciate) in HN. But I already have a few questions. I have a network like this:
Internet ---> Gateway ---> OPENVZ in HN Node ---> ISPConfig3 in one of the VEs --> A separate * voip server machine (not in VE).
I want to do virtual hosting with ISPConfig3 (http://www.howtoforge.com/forums/showthread.php?t=26988).
But the problem I am encountering is I have same ports running in VEs (like 80. 81, 443, 53 and so on) as well as in the external voip server with freepbx.
How to port forward different ports that comes to the OpenVZ Proxmox-Fridu Firewall machine in such a case to different machines?
Second, I would like to host my own DNS server (which already is installed in ISPConfig3 VE, in this case it is MyDNS). How can I assign two public IPs to run two different instances of DNS server in the same machine? I am a bit confused, with the IP_TWO statement. Where do I need to specify in proxmox installation?
Thanks!
PS: If you wish I can render some help to proof-read and copywrite some of the articles which has some typos and grammatical mistakes. Let me know.
============ Fulup Respond =============
Good to see that now its working :)
1) Would love some help on typo, spelling and other English errors, please contact me by mail http://www.fridu.org/contact-fulup
2) I've some issue to understand your network architecture. Your alternate VOIP server must be connected either at the gateway level or through a second NIC from your HN. In first case Fridu-firewall cannot provide any help, in second case your external machine can be view as a VE from Fridu-firewall point of view.
3) IP_TWO and multiple zone, is only if you have more than one public IP pointing to your HN (on fridu I've two public IPs, but your may get anything on between 1 and more than 16 depending on your hosting plan)
4) For Virtual hosting, you cannot leverage it with Firewall port-forwarding, this is the reason why on Fridu I do use pound reverse proxy to handle virtual hosting. In fact it is theoretically possible, but in the real world, it is a much better idea to use a reverse proxy. This being said you can either run the reverse proxy on VE or HN. Nevertheless if you have more than one PUBLIC-IP available you can still use virtual hosting for each given public-ip.
5) While running to independent instances of DNS server using OpenVZ+VM-firewall is possible, it is nevertheless a bad idea. The reason for imposing two DNS is failover support, if you chose to run both on the same hardware box, any major error will kill both of them :( This being said in order to nevertheless make it, you only need to define two zones (one per public-ip) and attache one guest to each of them (TIP: do not forget than DNS use UDP for request but TCP for zones transfert)
My configurtaions:
# zones.conf
CreateZone NAME=zOne NIC=vmbr0 EXT=$IP_ONE BR=venet0 INT=192.168.9.156 MASK=255.255.255.0
1st-common.conf
IP_ONE=public IP
# hypervisor.conf
CreateApp NAME=SSH ZONE=none EXT=tcp:22 INT=vmbr0
CreateApp NAME=WWW ZONE=none EXT=tcp:80 INT=vmbr0
CreateApp NAME=SSL ZONE=none EXT=tcp:443 INT=vmbr0
# vz-openssh.conf
CreateApp NAME=SSH ZONE=zOne EXT=tcp:2215 INT=192.168.9.156:22
CreateApp NAME=WWW ZONE=zOne EXT=tcp:8015 INT=192.168.9.156:80
CreateApp NAME=TOM ZONE=zOne EXT=tcp:8815 INT=192.168.9.156:8180
I could not figure out where did I go wrong?
=========== Fulup response ===================================
1) It is normal that tuning.conf does not change anything it is only necessary for complex configuration (ex:VPN)
2) CreateZone INT=192.168.9.156 should be INT=192.168.9.0 INT=xx.xx.xx.xx is a network mask not an IP address.
3) CreateZone NIC=vmbr0 is probably wrong because "vmbr0" is not your Ethernet interface!!! Looking to the name is must be a network bridge. Check this with "brctl show", when this bridge will be removed you will probably come back to something more traditional like "NIC=eth0"
Note: Looks like you're trying to used "veth" and not "venet". With VM-firewall Open-VZ user should always select "venet". Even if it technically possible to use VM-firewall+veth, outside very special cases like benchmarking/education to compare both venet/veth technologies,Open-VZ+VM-firewall users MUST chose venet (http://wiki.openvz.org/Venet)
thanks
MY CONFIG
IP_ONE=10.10.10.12
IP_TWO=192.168.1.40
CreateZone NAME=zOne NIC=eth0 EXT=$IP_ONE BR=venet0 INT=10.10.101.0 MASK=255.255.255.0
CreateZone NAME=zTwo NIC=eth0 EXT=$IP_TWO BR=venet0 INT=10.10.102.0 MASK=255.255.255.0
# Hyperviser Application Port Forwarding
CreateApp NAME=DOM0_SSH ZONE=none EXT=tcp:22 INT=eth0
CreateApp NAME=DOM0_WWW ZONE=none EXT=tcp:80 INT=eth0
CreateApp NAME=DOM0_SSL ZONE=none EXT=tcp:443 INT=eth0
CreateApp NAME=DOM0_VPNt ZONE=none EXT=tcp:563 INT=eth0
# Zone one Application ports Forwarding
CreateApp NAME=Mail_SMTP ZONE=zOne EXT=tcp:25 INT=10.10.101.1:2525
CreateApp NAME=Mail_IMAP ZONE=zOne EXT=tcp:993 INT=10.10.101.1:993
CreateApp NAME=Domi_WEB ZONE=zTwo EXT=tcp:80 INT=10.10.102.2:80
CreateApp NAME=Domi_SSH ZONE=zTwo EXT=tcp:22 INT=10.10.102.2:22
CreateApp NAME=Bren_SSH ZONE=zOne EXT=tcp:2216 INT=10.10.101.5:22
CreateApp NAME=Bren_WEB ZONE=zOne EXT=tcp:8016 INT=10.10.101.5:80
======== Fulup Respond =======================
GOOD NEWS: what you're trying to acheive is working out of the box :)
BAD NEWS: you took config sample without touching it, and it would be strange that it fit your environment :(
==============================================
This being said: all external port cannot be lock with this config. You open port 22/SSH with zone=none in which case this port will be open even if your external IP address was wrong.
Advice:
- simplify your config,a nd move to multi-file model as in fw-rules/openvz
- triple check your public-IP (both your IP_ONE and IP_TWO are not routable !!!)
- make sure your VM are reachable at 10.10.10x.xyz
- verify your config file is in fw-rules/default[.conf] or force config=xxxx in command line
Verification
- Fridu-firewall display ;# verify you activate the config file you want
- Fridu-firewall test dump=/tmp/iptables.dump ;# check your low level rules
- iptables -L | grep ssh ; # should see "anywhere tcp dpt:ssh"
- Never forget to do your nmap check from Internet, cannot work from hypervisor ;# typical error
Outside if this it's guaranty to work :)
It's shame to admit, but the problem was my (other) firewall, which blocked access to the openvz from hardware node to the only other host I was testing the access. This fact together whith the fact, that I was unable to tap to the guest system from the hardware node itself via it's _external_ interface (which as I understand now is a normal behiavour) pushed me to write the previous letter.
Thank you very much for publishing this simple firewall script as well as all other howtos!
Adam
==== Fulup respond ==== I love problems, when they solve by themselves :)
I've set up openvz on ubuntu server 8.04, with your Fridu-firewall. The host has only one nic "eth0" with static IP 192.168.3.46. Yes, it's private IP, but in my testing environment it might be considered public. The guest has IP 192.168.11.200 and ssh deamon up and running correctly.
Here goes my minimalistic configuration:
1st-common.conf:
IP_ONE=192.168.3.xx
zones.conf
CreateZone NAME=zOne NIC=eth0 EXT=$IP_ONE BR=venet0 INT=192.168.11.0 MASK=255.255.255.0
hypervisor.conf:
CreateApp NAME=SSH ZONE=none EXT=tcp:22 INT=eth0
tuning.conf: (I left almost everything untouched, as I don't really understand what it does)
DoIt iptables -A after-forwarding -i venet+ -o venet+ -j ACCEPT
DoIt iptables -A after-input -i tun+ -j ACCEPT
DoIt iptables -A after-forwarding -i tun+ -o venet+ -j ACCEPT
DoIt iptables -A after-forwarding -i venet+ -o tun+ -j ACCEPT
I've commented out the last line, as i do not wish to give two "public" IPs.
vz.conf: I wish to forward internal port 22 to external 2022
CreateApp NAME=SSH ZONE=zOne EXT=tcp:2022 INT=192.168.11.200:22
Now, the guest has full access to the internet. I'm able to connect to the ssh deamon from host, if I type "ssh 192.168.11.200" (and of course get "open" port report with "nmap 192.168.11.200 -p 22
"). Typing "ssh 192.168.3.xx -p 2022" doesn't work on any computer on 192.168.3.0/24 subnet, nor "nmap 192.168.3.xx -p 2022" doesn't show open port.
===== Fulup Response =====
*** you do not need "tuning.conf" this file is only necessary when running multiple zones and/or a VPN (just delete it).
*** the rest of your config is fine. The two most typical errors you may have are:
1) you have an other firewall that locks port 22 on your guest (verify packets reach your guest "tcpdump -i venet0 port 22" on your guest)
2) you try to access service directly from the hypervisor (ssh -p 2022 192.168.3.46 will only work from internet)
3) your infrastructure (router, modem, operator, ....) lock port 2022
--- Outside of that it should work :)