Running a PPTP Server Behind a NAT Firewall


For allowing PPTP access in the other direction where the remote system would need to connect to an internal PPTP server through a netfilter/iptables firewall, the following example DNAT rules should work:

 # assuming eth0 is your external interface, and that you have a PPTP server at 10.10.10.5 $IPTABLES -t nat -A PREROUTING -i eth0 -p tcp --dport 1723 -j DNAT --to-destination 10.10.10.5 $IPTABLES-A FORWARD -i eth0 -m state --state NEW -p tcp -d 10.10.10.5 --dport 1723 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -m state --state NEW -p 47 -d 10.10.10.5  -j ACCEPT $IPTABLES -t nat -A PREROUTING -i eth0 -p 47 -j DNAT to-destination 10.10.10.5 $IPTABLES -t nat -A POSTROUTING -o eth0 -j MASQUERADE 

PPTP: Firewall Cannot Establish PPTP VPNs

Extended Description: You have a NAT/MASQUERADING firewall that is PPTP-capable. This firewall acts as an end node, NAT/MASQUERADING traffic into the PPTP VPN itself so all connections inside the PPTP VPN, as well as to the external network, appear to be coming from the firewall.

Figure 19.5. Firewall cannot establish PPTP VPNs.


This is a fairly basic configuration and in practice much more simple to implement than actually trying to NAT PPTP traffic through the firewall. In this configuration, the firewall needs only to establish a PPTP connection to the remote system and then using NAT rules, NAT/MASQUERADE the traffic from its internal systems into the PPTP VPN. For this type of setup, I cannot recommend the pptpclient project enough: http://pptpclient.sourceforge.net/. The documentation provided for numerous configurations just cannot be overlooked. They cover numerous scenarios dealing with the automatic establishment of the PPTP VPN, DSL issues, and installing the encryption modules required to secure the connection.

In this configuration you can borrow a rule right from the IPSEC section here dealing with masquerading traffic from one network across the VPN tunnel using an SNAT rule:

 $IPTABLES -t nat -A POSTROUTING -o ppp0   \ -s 10.10.12.0/24 -d 10.10.11.0/24 -j SNAT \ --to-source 10.10.12.1 

The primary difference between this rule and the IPSEC rule here is that PPTP encapsulates a PPP connection, so our device name is different.

PPTP: Firewall Can Establish Connections to a Remote VPN Server, but Traffic Does not Route Correctly Inside the VPN

Extended Description: Two firewalls are configured to connect RFC 1918 networks to each other over a PPTP VPN. In the following example, the left side network, 10.10.10.0/24, is attempting to be connected to the right side network, 10.10.11.0/24, over a PPTP connection.

This is the type of configuration you would use if you were attempting to join two remote networks together over the Internet, in the case of migrating from a legacy WAN to a VPN over the Internet. In this example, we have two RFC 1918 networks, 10.10.10.0/24 and 10.10.11.0/24, and two firewalls, Host-A and Host-B.

The first step into diagnosing problems with this configuration is to ensure that the VPN session itself is being established, which you can verify by monitoring the log files or using a sniffer like ethereal. In general, leaving out the obvious authentication or availability issues between Host-A and Host-B, the MTU path discovery issues are the first thing to look at when performing your PPTP diagnostics.

Figure 19.6. Traffic does not route through PPTP VPN.


As PPTP also uses GRE protocol 47, it is also necessary to build your kernel with GRE support, documented here, and if that support is modular, the ip_gre module is loaded in the kernel:

 modprobe ip_gre 

Note

Versions of pptpclient 1.2.0 and greater no longer require this.


A symptom of this not being loaded, aside from the obvious that the VPN isn't working, will be ICMP protocol unreachable reply messages in your sniffer dump on protocol 47.

Just like the IPSEC rules here, if your NAT/MASQUERADING rule is not bound to your external interface, you may be rewriting your VPN traffic so it appears to be coming from your external interface on your firewall. The following extremely simple example rule shows how to ensure that this traffic is not being NAT-ed:

 #Connection tracking rules $IPTABLES -A INPUT  -m state state    \   ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state state    \   NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state state   \   NEW,ESTABLISHED,RELATED -j ACCEPT # eth0 is our external dynamic interface, eth1 is our internal interface $IPTABLES -t nat -A POSTROUTING -o eth0 -j MASQUERADE 

Again, these are very simple rules and you should create specific rules for your firewall. The FORWARD rules here will forward any traffic, from either side of the firewall, which is not what you want. Make sure that you configure the sources, via -s, that you want to FORWARD NEW traffic for, and also use -i and -o interface settings to define the input and output interfaces on your firewall for that traffic.

Of course, there's always more than one way to do it. The following rules from the pptpclient website demonstrate a similar more elaborate configuration to route traffic between both networks:

Host-A configuration rules:

 route add -net 192.168.0.0/16 netmask 255.255.0.0 dev ppp0 $IPTABLES --insert OUTPUT 1 --source 0.0.0.0/0.0.0.0  \   --destination 192.168.0.0/16 --jump ACCEPT -o ppp0 $IPTABLES --insert INPUT 1 --source 192.168.0.0/16    \ --destination 0.0.0.0/0.0.0.0 --jump ACCEPT -i ppp0 $IPTABLES --insert FORWARD 1 --source 0.0.0.0/0.0.0.0 \ --destination 192.168.0.0/16 --jump ACCEPT -o ppp0 $IPTABLES --insert FORWARD 1 --source 192.168.0.0/16 \ --destination 0.0.0.0/0.0.0.0 --jump ACCEPT $IPTABLES --table nat --append POSTROUTING -o ppp0 \ --jump MASQUERADE $IPTABLES --append FORWARD --protocol tcp \   --tcp-flags SYN,RST SYN --jump TCPMSS    \   clamp-mss-to-pmtu 

Host-A

 route add -net 10.10.11.0/24 netmask 255.255.0.0 dev ppp0 

This first rule sets a static route to 10.10.11.0 network on Host-A.

 $IPTABLES --insert OUTPUT 1 --source 10.10.10.0/24 \   --destination 10.10.11.0/24 --jump ACCEPT -o ppp0 

This second rule instructs iptables to redirect all outbound traffic from the 10.10.10.0/24 with the destination network 10.10.11.0/24 only out the ppp0 device.

 $IPTABLES --insert INPUT 1 --source 10.10.11.0/24  \   --destination 10.10.10.0/24 --jump ACCEPT -i ppp0 

This third rule sets the INPUT policy that traffic on the ppp0 interface, from the 10.10.11.0/24 network destined to the 10.10.10.0/24 network, be accepted.

 $IPTABLES --insert FORWARD 1 --source 10.10.10.0/24 \   --destination 10.10.11.0/24 --jump ACCEPT -o ppp0 

The fourth rule in this chain instructs netfilter to forward packets from the source network 10.10.10.0/24 and a destination of 10.10.11.0/24 out the ppp0 interface. Without this rule, only the Host-A firewall itself would be allowed to communicate with systems on the 10.10.11.0/24 network.

 $IPTABLES --insert FORWARD 1 --source 10.10.11.0/24 \   --destination 10.10.10.0/24 --jump ACCEPT i ppp0 

This fifth rule sets the FORWARD policy for traffic from the 10.10.11.0/24 network, destined to the 10.10.10.0/24 network, be accepted on the ppp0 interface.

 $IPTABLES --append FORWARD --protocol tcp \   --tcp-flags SYN,RST SYN --jump TCPMSS   \   clamp-mss-to-pmtu 

This final rule is used on 2.4 kernels to deal with the oft-repeated MTU path discovery issue when dealing with DSL, PPPoE, and other situations where the MTU is causing problems with your connections.

Using a free/openswan VPN to Secure a Wireless Network

This example is specifically for securing a wireless network, but it could just as easily be used to create a "road warrior" VPN configuration in conjunction with netfilter using this example.

In this scenario, we have a wireless segment (192.168.32.0/24) that we would like to secure using netfilter and an openswan IPSEC VPN. Our access point will act as a DHCP server, and we will configure our firewall (Firewall-A) to drop all traffic from the 192.168.32.0/24 network attempting to traverse the firewall. This is to ensure that if someone manages to hop on the wireless network by cracking the WEP or WAP keys, he or she still cannot access systems on the other side (internal network) of your firewall, or the Internet. Of course, they will be able to attack nodes on the wireless segment, so you might want to establish local firewall rules on all your hosts as shown in the example at the end of this section.

Figure 19.7. A wireless network secured using firewall rules and IPSEC VPNs.


The intent of this design is to

  1. Secure your wireless communications from eavesdropping.

  2. Secure your wireless network from becoming an open access point and prevent attackers from accessing your internal network or the Internet.

We will assume that you have configured your access point correctly and that the wireless network (192.168.32.0/24) is functioning properly. Our firewall (Firewall-A) is located at the IP address 192.168.32.1.

Configure your firewall for your "road warriors" using openswan. First we need to set up our ipsec mechanism. Consult the documentation for configuring openswan in your kernel. In this example, our firewall is running a 2.4.26 kernel and openswan 2.1.2. Firewall-A's /etc/ipsec.conf:

 # Host-A is a firewall running redhat 9 config setup         interfaces="ipsec0=eth0 ipsec1=eth1 ipsec2=eth2"         # Debug-logging controls:  "none" for (almost) none, "all" for lots.         # klipsdebug=all         # plutodebug=dns conn wireless     left=192.168.32.1                 # Gateway's information     leftid=@firewall-a     leftsubnet=0.0.0.0/0      #     #leftnexthop=%defaultroute     # correct in many situations     leftrsasigkey=0sAQOF...     right=%any                     # Wildcard: we don't know the laptop's IP     rightid=@host-b     rightrsasigkey=0sAQOit...     auto=add                       # authorizes but doesn't start this                                    # connection at startup 

  1. We configure our laptop to connect to the firewall. The key here is that the subnet for our VPN is 0.0.0.0/0, which is the world at large, as it were. Our laptop in this example is running a Redhat 2.6.6 kernel, with openswan 2.1.3. The important difference between a 2.4 and a 2.6 kernel is that 2.6 comes with IPSEC by default. The openswan patches integrate with the existing IPSEC implementation in the 2.6.x kernel:

    Host-B's /etc/ipsec.conf:

     # Host-B is a laptop running SuSE 9.1 # relevant section "road" is at the bottom. The rest is the SuSE default version 2.0     # conforms to second version of ipsec.conf specification # basic configuration config setup         # Debug-logging controls:  "none" for (almost) none, "all" for lots.         #klipsdebug=all         #plutodebug=all # default settings for connections conn %default         # Default: %forever (try forever)         #keyingtries=3         # Sig keys (default: %dnsondemand)         leftrsasigkey=%cert         rightrsasigkey=%cert         # Lifetimes, defaults are 1h/8hrs         #ikelifetime=20m         #keylife=1h         #rekeymargin=8m # OE policy groups are disabled by default conn block         auto=ignore conn clear         auto=ignore conn private         auto=ignore conn private-or-clear         auto=ignore conn clear-or-private         auto=ignore conn packetdefault         auto=ignore conn road     left=%defaultroute             # Picks up our dynamic IP     leftid=@host-b                   # Local information     leftrsasigkey=0sAQOC....  # Local key     right=192.168.32.1             # Remote information     rightsubnet=0.0.0.0/0         # Remote subnet is set to "everything"     rightid=@firewall-a           # Remote information     rightrsasigkey=0sAQO....  # Remote key     auto=add                            # authorizes but doesn't start this 

  2. Verify your configuration settings by running the command: ipsec auto status on both systems. If your systems are configured correctly, the output will look like the following:

    Firewall-A (using the unsecured wireless IP of 192.168.32.1):

     000 "wireless": 0.0.0.0/0===192.168.32.1[@firewall-a]...%any[@host-b]; unrouted; eroute owner: #0 000 "wireless":   ike_life: 3600s; ipsec_life: 28800s; rekey_margin: 540s; rekey_fuzz: 100%; keyingtries: 0 000 "wireless":   policy: RSASIG+ENCRYPT+TUNNEL+PFS; prio: 0,32; interface: eth2; 000 "wireless":   newest ISAKMP SA: #0; newest IPsec SA: #0; 

    Host-B (using the unsecured wireless IP of 192.168.32.190):

     [root@host-b root]# ipsec auto status 000 "wireless": 192.168.32.190[@Host-B,S=C]...192.168.32.1[@Firewall- A,S=C]===0.0.0.0/0; unrouted; eroute owner: #0 000 "wireless":   ike_life: 3600s; ipsec_life: 28800s; rekey_margin: 540s; rekey_fuzz: 100%; keyingtries: 0 000 "wireless":   policy: RSASIG+ENCRYPT+TUNNEL+PFS; prio: 32,0; interface: eth1; 000 "wireless":   newest ISAKMP SA: #0; newest IPsec SA: #0; 

    If your system does not show the script here, then probably you have an error in your configuration files. openswan will log these messages to syslog. In the case of the systems in our example, this was to /var/log/messages.

  3. Establish your firewall rules. We have two networks, an internal wired 10.10.10.0/24 network, and a wireless 192.168.32.0/24 network. In addition, our firewall runs a transparent squid proxy, a caching DNS server, and the reaim (http://reaim.sf.net) instant messaging proxy:

     #!/bin/sh IPTABLES="/sbin/iptables" EXTERNAL="eth0" INTERNAL="eth1" WIRELESS="eth2" VPN="ipsec0" # clear our old firewall rules $IPTABLES -F $IPTABLES -X echo "Setting default filter policy" $IPTABLES -P INPUT   DROP $IPTABLES -P OUTPUT  DROP $IPTABLES -P FORWARD DROP # Set our connection tracking rules $IPTABLES -A INPUT  -m state state  \   ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state state  \   NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state state \   ESTABLISHED,RELATED -j ACCEPT # For PPPoE, DSL, and other MTU sensitve connections $IPTABLES -A OUTPUT -o $EXTERNAL -p tcp \   --tcp-flags SYN,RST SYN -j TCPMSS clamp-mss-to-pmtu # Allow SSH on everything $IPTABLES -A INPUT -p tcp --dport 22 -j ACCEPT # internal rules $IPTABLES -A INPUT -i $INTERNAL -p tcp \   --dport 5190 -j ACCEPT $IPTABLES -A INPUT -i $INTERNAL -p tcp \   --dport 1863 -j ACCEPT $IPTABLES -t nat -A PREROUTING -i $INTERNAL \   -p tcp --dport 5190 -j REDIRECT --to-ports 5190 $IPTABLES -t nat -A PREROUTING -i $INTERNAL \   -p tcp --dport 1863 -j REDIRECT --to-ports 1863 # A for loop to duplicate rules on trusted interfaces INTERFACES="$INTERNAL $VPN" for i in $INTERFACES; do   #  Allow DNS traffic $IPTABLES -A INPUT -p tcp --dport 53 -i $i -j ACCEPT $IPTABLES -A INPUT -p udp --dport 53 -i $i -j ACCEPT # Allow SQUID connections $IPTABLES -A INPUT -p tcp --dport 3128 -i $i \   -j ACCEPT $IPTABLES -t nat -A PREROUTING -i $i -p tcp  \   --dport 80 -j REDIRECT --to-port 3128 # Reaim connections $IPTABLES -A INPUT -i $i -p tcp --dport 5190 \   -j ACCEPT $IPTABLES -A INPUT -i $i -p tcp --dport 1863 \   -j ACCEPT $IPTABLES -t nat -A PREROUTING -i $i -p tcp  \   --dport 5190 -j REDIRECT --to-ports 5190 $IPTABLES -t nat -A PREROUTING -i $i -p tcp  \   --dport 1863 -j REDIRECT --to-ports 1863 done # IPSEC rules. This allows IPSEC traffic to be forwarded through the VPN # $IPTABLES -N IPSEC $IPTABLES -A INPUT -j IPSEC $IPTABLES -A FORWARD -i $VPN -j IPSEC $IPTABLES -A IPSEC -i $WIRELESS -p udp --dport 500 \   -j ACCEPT $IPTABLES -A IPSEC -i $WIRELESS -p ESP -j ACCEPT # Masquerading rules, we use this if we have a dynamic # IP $IPTABLES -t nat -A POSTROUTING -o $EXTERNAL -j MASQUERADE # SNAT we would use this if we had a static IP # $IPTABLES -t nat -A POSTROUTING -i eth1 \ #  -o $EXTERNAL -j SNAT --to $EXTERNALIP # debugging rule, or for the paranoid. This will catch all dropped packets by the firewall $IPTABLES -A INPUT -p all  -m limit --limit 1/second \   -j LOG  --log-level info --log-prefix "STEALTH --  \   DROP "  --log-tcp-sequence  --log-tcp-options      \   --log-ip-options # Enable IP Forwarding in the kernel echo "1" > /proc/sys/net/ipv4/ip_forward 

    The following is a sniffer dump of the 192.168.32.0/24 network from the firewall's eth2 interface, prior to the IPSEC tunnel being established to the host 192.168.32.190 (Host-B):

     [root@firewall-a rc.d]# tethereal -i eth2 host 192.168.32.190 Capturing on eth0   0.000000 192.168.32.190 -> 68.98.150.6  TCP 58862 > webcache [SYN, ECN, CWR] Seq=3608226472 Ack=0 Win=5840 Len=0 MSS=1460 TSV=34015029 TSER=0 WS=0   2.992793 192.168.32.190 -> 68.98.150.6  TCP 58862 > webcache [SYN, ECN, CWR] Seq=3608226472 Ack=0 Win=5840 Len=0 MSS=1460 TSV=34015329 TSER=0 WS=0   8.994929 192.168.32.190 -> 68.98.150.6  TCP 58862 > webcache [SYN, ECN, CWR] Seq=3608226472 Ack=0 Win=5840 Len=0 MSS=1460 TSV=34015929 TSER=0 WS=0  20.995165 192.168.32.190 -> 68.98.150.6  TCP 58862 > webcache [SYN, ECN, CWR] Seq=3608226472 Ack=0 Win=5840 Len=0 MSS=1460 TSV=34017129 TSER=0 WS=0  44.998586 192.168.32.190 -> 68.98.150.6  TCP 58862 > webcache [SYN, ECN, CWR] Seq=3608226472 Ack=0 Win=5840 Len=0 MSS=1460 TSV=34019529 TSER=0 WS=0 

    And this is the sniffer dump after establishing the IPSEC VPN:

     [root@firewall-a rc.d]# tethereal -i eth2 host 192.168.32.190   1.019722 192.168.32.190 -> 192.168.32.1 ESP ESP (SPI=0x258d56d0)   1.019830 192.168.32.190 -> 192.168.32.1 ESP ESP (SPI=0x258d56d0)   1.020038 192.168.32.1 -> 192.168.32.190 ESP ESP (SPI=0xe180e07f)   1.019921 192.168.32.190 -> 192.168.32.1 ESP ESP (SPI=0x258d56d0)   1.020017 192.168.32.190 -> 192.168.32.1 ESP ESP (SPI=0x258d56d0)   1.020111 192.168.32.190 -> 192.168.32.1 ESP ESP (SPI=0x258d56d0)   1.020621 192.168.32.1 -> 192.168.32.190 ESP ESP (SPI=0xe180e07f) 



    Troubleshooting Linux Firewalls
    Troubleshooting Linux Firewalls
    ISBN: 321227239
    EAN: N/A
    Year: 2004
    Pages: 169

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net